首页 文章

如何将angular2与jinja2模板和烧瓶结合起来

提问于
浏览
3

在Angular 1取得巨大成功之后,我开始使用Angular 2.我遵循了QuickstartTour of Heroes教程,一切都像魅力一样 .

Lite服务器开始启动,我看到 tsc 在监视模式下运行,我甚至看到BrowserSync被连接起来 . 大!

但是,我需要开始让事情变得更加现实 .

Instead of using lite server, how do I get all this working using a flask dev or gunicorn server, serving the initial index.html file as a rendered jinja template?

给烧瓶开发服务器一个非常有用的尝试,我基本上将示例index.html的内容从教程复制到我的jinja模板,然后运行 npm run tsc:w ,最后启动我的烧瓶开发服务器并希望最好 . 事情编译得很好 . 但是在浏览器中我看到了问题:

angular2-polyfills.js:332 Error: SyntaxError: Unexpected token <
    at ZoneDelegate.invoke (http://127.0.0.1:5000/static/node_modules/angular2/bundles/angular2-polyfills.js:332:29)
    at Zone.run (http://127.0.0.1:5000/static/node_modules/angular2/bundles/angular2-polyfills.js:227:44)
    at http://127.0.0.1:5000/static/node_modules/angular2/bundles/angular2-polyfills.js:576:58
Evaluating http://127.0.0.1:5000/app/main.js
Error loading http://127.0.0.1:5000/app/main.js`

看着罪魁祸首transpile main.js文件,我看到:

(function(System, SystemJS, require) {<!doctype html>
<html>
<head lang='en'>

所以,是的,这不会起作用......显然我的布线是乱七八糟的 .

垫片,polyfill,反应扩展,systemjs,angular2本身有很多黑魔法,然后在tsc和lite服务器中抛出 . 不可否认,我还没有完成所有这些工作,这需要时间,但我希望能够让我的项目很快进入理智状态 .

(我不介意在开发中使用lite服务器(BrowserSync是一个很好的特权),只要我可以配置它代理将返回渲染jinja模板的真正的烧瓶服务器 . )

Update

这是实际的模板索引文件,我做了一些小的改动:

<!doctype html>
<html>
  <head lang="en">
    {% block head %}

    <meta charset="utf-8">

    <title>Angular 2 QuickStart</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">    
    <link rel="stylesheet" href="styles.css">
    <!-- 1. Load libraries -->
    <!-- IE required polyfills, in this exact order -->
    <script src="node_modules/es6-shim/es6-shim.min.js"></script>
    <script src="node_modules/systemjs/dist/system-polyfills.js"></script>
    <script src="node_modules/angular2/es6/dev/src/testing/shims_for_IE.js"></script>   
    <script src="node_modules/angular2/bundles/angular2-polyfills.js"></script>
    <script src="node_modules/systemjs/dist/system.src.js"></script>
    <script src="node_modules/rxjs/bundles/Rx.js"></script>
    <script src="node_modules/angular2/bundles/angular2.dev.js"></script>
    <!-- 2. Configure SystemJS -->
    <script>
      System.config({
        packages: {        
          app: {
            format: 'register',
            defaultExtension: 'js'
          }
        }
      });
      System.import('app/main')
            .then(null, console.error.bind(console));
    </script>

    {% endblock %}
  </head>
  <!-- 3. Display the application -->
  <body>
    {% block content %}{% endblock %}

    <my-app>Loading...</my-app>

    <script>
      (function(globals) {
        this.MyConfig = {
          staticDir: '{{ config["STATIC_DIR"] }}'
        };
      }(this));
    </script>
  </body>
</html>

2 回答

  • 1

    I had the same problem and here is how I solved it;

    第1步

    目录结构如下:

    • MyAppName
    • ServerApp
      --- //...flask文件在这里
    • ClientApp
      ---节点模块
      --- app
      --- //...更多节点角度应用程序文件

    我使用以下代码在URL .../client-app/... 中公开了我的烧瓶应用程序中的ClientApp文件夹:

    from flask import Flask, send_from_directory
    import os
    
    BASE_URL = os.path.abspath(os.path.dirname(__file__))
    CLIENT_APP_FOLDER = os.path.join(BASE_URL, "ClientApp")
    
    # This is required by zone.js as it need to access the
    # "main.js" file in the "ClientApp\app" folder which it
    # does by accessing "<your-site-path>/app/main.js"
    @app.route('/app/<path:filename>')
    def client_app_app_folder(filename):
        return send_from_directory(os.path.join(CLIENT_APP_FOLDER, "app"), filename)
    
    # Custom static data
    @app.route('/client-app/<path:filename>')
    def client_app_folder(filename):
        return send_from_directory(CLIENT_APP_FOLDER, filename)
    

    第2步

    转到你的 index.html 文件(我把我放在 ServerApp\templates\index.html 以便我可以简单地做 render_template('index.html') )并使它看起来像这样:

    <html>
      <head>
        <title>Angular 2 QuickStart</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link rel="stylesheet" href="client-app/assets/css/style.css">
    
        <!-- 1. Load libraries -->
         <!-- Polyfill(s) for older browsers -->
        <script src="client-app/node_modules/es6-shim/es6-shim.min.js"></script>
    
        <script src="client-app/node_modules/zone.js/dist/zone.js"></script>
        <script src="client-app/node_modules/reflect-metadata/Reflect.js"></script>
        <script src="client-app/node_modules/systemjs/dist/system.src.js"></script>
    
        <!-- 2. Configure SystemJS -->
        <script src="client-app/systemjs.config.js"></script>
        <script src=""></script>
        <script>
          System.import('app').catch(function(err){ console.error(err); });
        </script>
      </head>
    
      <!-- 3. Display the application -->
      <body>
        <my-app>Loading...</my-app>
      </body>
    </html>
    

    the 'client-app' prepended to the paths is the route I chose to expose my client_app_folder() function at

    第3步

    在这种情况下配置客户端应用程序's package finder to use the set route (' client-app / ...' . 我使用system.js,因此我的 systemjs.config.js 文件看起来像这样:

    (function(global) {
    
      // map tells the System loader where to look for things
      var map = {
        'app':                        'client-app/app', // 'dist',
        'rxjs':                       'client-app/node_modules/rxjs',
        'angular2-in-memory-web-api': 'client-app/node_modules/angular2-in-memory-web-api',
        '@angular':                   'client-app/node_modules/@angular'
      };
    
      // packages tells the System loader how to load when no filename and/or no extension
      var packages = {
        'app':                        { main: 'main.js',  defaultExtension: 'js' },
        'rxjs':                       { defaultExtension: 'js' },
        'angular2-in-memory-web-api': { defaultExtension: 'js' },
      };
    
      var packageNames = [
        '@angular/common',
        '@angular/compiler',
        '@angular/core',
        '@angular/http',
        '@angular/platform-browser',
        '@angular/platform-browser-dynamic',
        '@angular/router',
        '@angular/router-deprecated',
        '@angular/testing',
        '@angular/upgrade',
      ];
    
      // add package entries for angular packages in the form '@angular/common': { main: 'index.js', defaultExtension: 'js' }
      packageNames.forEach(function(pkgName) {
        packages[pkgName] = { main: 'index.js', defaultExtension: 'js' };
      });
    
      var config = {
        map: map,
        packages: packages
      }
    
      // filterSystemConfig - index.html's chance to modify config before we register it.
      if (global.filterSystemConfig) { global.filterSystemConfig(config); }
    
      System.config(config);
    
    })(this);
    

    I only modified the map variable

    一帆风顺!

  • 8

    在寻找同一个问题的答案时,我被提醒要改变角度1中的插值字符 . 可以找到两个角度2的位置,但它很容易在jinja2侧改变 . 用你想要的设置jinja2环境选项字符:

    JINJA_ENV = jinja2.Environment(
      loader=jinja2.FileSystemLoader(os.path.dirname(__file__)),
      extensions=['jinja2.ext.autoescape'],
      block_start_string= '{[%',
      block_end_string='%]}',
      variable_start_string='{[',
      variable_end_string=']}',
      comment_start_string='{#',
      comment_end_string='#}',
      autoescape=True
    )
    

    希望我在这里使用兼容的字符串,我猜我会发现! (见http://jinja.pocoo.org/docs/dev/api/环境选项)

相关问题