【问题标题】:Flask Jinja2 template syntax conflicts with AngularJS (jinja2.exceptions.UndefinedError:)Flask Jinja2 模板语法与 AngularJS 冲突 (jinja2.exceptions.UndefinedError:)
【发布时间】:2020-05-27 03:52:07
【问题描述】:

如何从 angularjs 访问 html 中的 $scope.list?

jinja2.exceptions.UndefinedError: 'car' is undefined

ma​​in.js

(function () 
{
    'use strict';

    angular.module('WordcountApp', [])    
    
    .controller('WordcountController', ['$scope', 
                                        function($scope) 
                                        {
                                            $scope.some = 'jjj'
                                              
                                            console.log( "in WordcountController " , $scope.some)
                                              
                                            $scope.cars = [
                                                            {make: 'Mazda', model: 'Miata', year: 2001},
                                                            {make: 'Toyota', model: 'Prius', year: 2013},
                                                            {make: 'Tesla', model: 'S', year: 2015},
                                                            {make: 'BMW', model: '325i', year: 2012}
                                                          ]
                                        }
                                       ]
                );
}()
);

index.html

<!DOCTYPE html>
<html ng-app = "WordcountApp" >

    <head>
        <script src = "https://ajax.googleapis.com/ajax/libs/angularjs/1.7.9/angular.min.js"> </script>
        <script src = "static/main.js" > </script>
    </head>
    
    <body ng-controller = "WordcountController">
        <ul ng-repeat = "car in cars" >
            <p> {{ car.make }} </p>
        </ul>
    </body>
</html>

app.py

from flask import Flask 
from flask import render_template   
from flask import request           

app = Flask( __name__ )
displayText = 'Default text from Python'

@app.route('/', methods=['GET', 'POST'])
def index():
    return render_template('index.html')

@app.route("/writeOutput", methods=['POST'])
def writeOutput():
    global displayText
    
    print("request.get_json():- ", request.get_json())
    
    displayText = request.get_json()['myOutput']['myText']
    
    print ("from POST " , displayText)
    return displayText


@app.route("/displayPreviousText", methods=['GET'])
def displayPreviousText():
    global displayText
    return displayText 

if __name__ == "__main__":
    app.run()

我以python app.py 运行此应用程序

错误:jinja2.exceptions.UndefinedError: 'car' is undefined

从angular访问html中列表的方法是什么?

【问题讨论】:

  • 如果我复制你的代码就可以工作...所以问题出在其他地方
  • 您能发布您的 package.json 和任何构建/服务器配置文件吗?目前尚不清楚 Jinja 如何成为您发布的代码的一部分。 (即你是否使用 python 服务?)
  • @kskid19 很抱歉没有包含 python 代码。我现在已经做到了。请看。我正在使用 Flask。
  • @PetrAveryanov 请查看更新。感谢您试用我的代码。
  • 你可以打开你的index.html,你可以view page source点击static/main.js的链接。确保您可以打开该文件,如果没有,那么您应该学习如何读取静态文件。

标签: javascript python html angularjs jinja2


【解决方案1】:

您的错误 Error: jinja2.exceptions.UndefinedError: 'car' is undefined 与 JavaScript 无关。问题似乎如下-Jinja2 template renderer also relies on double curly braces same as AngularJS{{ your expression here }}。

有几种解决方案可以用来解决这个问题

  1. 您可以更改 Angular 的插值表示法,即

    angular.module('WordcountApp', [])
       .config(['$interpolateProvider', function($interpolateProvider) {
          $interpolateProvider.startSymbol('[[');
          $interpolateProvider.endSymbol(']]');
       }]);
    

    所以你的 javascript/html 代码应该如下所示

    (function () 
    {
      'use strict';
    
      angular.module('WordcountApp', [])
    
      // Setting up new interpolation delimiter which does not conflict with Jinja2
      .config(['$interpolateProvider', function($interpolateProvider) {
        $interpolateProvider.startSymbol('[[');
        $interpolateProvider.endSymbol(']]');
      }])
    
      .controller('WordcountController', ['$scope',  function($scope) {
            $scope.some = 'jjj'
        
            console.log( "in WordcountController " , $scope.some)
        
            $scope.cars = [
                {make: 'Mazda', model: 'Miata', year: 2001},
                {make: 'Toyota', model: 'Prius', year: 2013},
                {make: 'Tesla', model: 'S', year: 2015},
                {make: 'BMW', model: '325i', year: 2012}
            ]                                         
      }])
    
    }()
    );
    <!DOCTYPE html>
    <html ng-app = "WordcountApp" >
    
        <head>
            <script src = "https://ajax.googleapis.com/ajax/libs/angularjs/1.7.9/angular.min.js"> </script>
            <script src = "static/main.js" > </script>
        </head>
    
        <body ng-controller = "WordcountController">
            <ul ng-repeat = "car in cars" >
                <!-- Utilizing new interpolation delimiter -->
                <p> [[ car.make ]] </p>
            </ul>
        </body>
    </html>
    
     
  2. 另外,我相信更简单的方法应该像

    <ul ng-repeat = "car in cars" >
        <p> {{ '{{ car.make }}' }} </p>
    </ul>
    

    它将首先使用 Jinja2 模板,原始 HTML 的输出将是正确的 AngularJS 语法。但我不能 100% 确定这种方式,现在无法检查。

  3. 此外,在研究您的问题时,我发现了另一种可用于解决您的问题的解决方案。 Flask-Triangle 提供了一个过滤器 angular 来告诉 Jinja 表达式的求值是否必须呈现为 Angular 表达式。未定义的变量在 HTML 输出中按原样呈现。

    在这种情况下,您的 html 部分代码应如下所示

    <body ng-controller = "WordcountController">
        <ul ng-repeat = "car in cars" >
            <p> {{car.make|angular}} </p>
        </ul>
    </body>
    

    您可以阅读有关此解决方案的更多信息

【讨论】:

  • 我非常感谢您在这里所做的所有努力。感谢所有有用的链接和解释。
【解决方案2】:

这是因为烧瓶语法与 angular 冲突。

所以更改 Python 代码:

import os

from flask import Flask 
from flask import render_template
from flask import send_file, make_response, abort  
from flask import request           

app = Flask( __name__ )
displayText = 'Default text from Python'

@app.route('/', methods=['GET', 'POST'])
def index():
	return make_response(open('index.html').read())

@app.route("/writeOutput", methods=['POST'])
def writeOutput():
    global displayText

    print("request.get_json():- ", request.get_json())

    displayText = request.get_json()['myOutput']['myText']

    print ("from POST " , displayText)
    return displayText


@app.route("/displayPreviousText", methods=['GET'])
def displayPreviousText():
    global displayText
    return displayText 

if __name__ == "__main__":
    app.run()

return make_response(open('index.html').read())

而不是

render_template('index.html')

这样可以解决问题。

另一种方法是使用 Angular 的部分。

【讨论】:

  • 谢谢你。如果您能解释一下make_response(open('index.html').read()) 在做什么,那就更好了。请在您的答案中添加解释。
  • make response 用于将模板作为字符串发送而不是将其呈现为flask2模板,我从github.com/shea256/angular-flask/blob/…得到它
  • 这只是将响应作为字符串发送,而不是解析和插入 python 变量。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-21
  • 1970-01-01
  • 2018-09-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多