Flask Jinja2テンプレートの構文がAngularJSと競合します(jinja2.exceptions.UndefinedError :)

2020-02-12 javascript python html angularjs jinja2

angularjsからhtmlの$ scope.listにアクセスするにはどうすればよいですか?

jinja2.exceptions.UndefinedError: 'car'は未定義です

main.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のリストにアクセスする方法は何ですか?

Answers

エラーError: jinja2.exceptions.UndefinedError: 'car' is undefined is not related to JavaScript。問題は次のようです-Jinja2テンプレートレンダラーも、AngularJS {{ your expression here }} と同じ二重中括弧に依存してい {{ your expression here }}

これを解決するために使用できるいくつかのソリューションがあります

  1. Angular ieの補間表記を変更できます

    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. また、問題を調査しているときに、問題の解決に使用できるもう1つの解決策を見つけました。 Flask-Triangleは、式の評価をAngular式としてレンダリングする必要があるかどうかをJinjaに伝えるための角度フィルターを提供します。未定義の変数は、HTML出力でそのままレンダリングされます。

    この場合、htmlパーツコードは次のようになります。

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

    このソリューションの詳細を読むことができます

これは、フラスコの構文が角度と衝突したために起こりました。

したがって、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()

make_response(open( 'index.html')。read())を返します

の代わりに

render_template( 'index.html')

これで問題は解決します。

別の方法は、Angularのパーシャルを使用することです。

Related