Почему я не могу правильно отображать данные, хотя могу получать данные (angularjs с flask-restapi/jinja2)

Я пытался отлаживать около 2 часов, но безуспешно.

Это моя ошибка:

jinja2.exceptions.UndefinedError jinja2.exceptions.UndefinedError: «элемент» не определен

Я могу правильно получить данные ($scope.questions). введите здесь описание изображения

Мой index.html:

<html>

<head>
</head>

<body>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>

    <div ng-app="myApp" ng-controller="myCtrl">
        <div ng-repeat="item in questions">
            {{item.question}}
        </div>
    </div>

    <script>
        var app = angular.module('myApp', []);
        app.controller('myCtrl', function ($scope, $http) {
            $http({
                method: "GET",
                url: "http://127.0.0.1:5000/questions"
            }).then(function mySuccess(response) {
                $scope.questions = response.data;
            }, function myError(response) {
                $scope.myWelcome = response.statusText;
            });
        });
    </script>
</body>

</html>

Моя серверная часть:

import os

from flask import Flask, request, render_template, Response
from flask_restful import Resource, Api

app = Flask(__name__)
api = Api(app)

question_id_serial = 2
questions = {
    1: {
        'id': 1,
        'question': 'Is this hard?',
    },
    2: {
        'id': 2,
        'question': 'Who is going to win the SuperBowl in 2017?',
    }
}

answer_id_serial = 6
answers = {
    1: {
        'id': 1,
        'question_id': 1,
        'answer': 'Yes',
        'count': 0
    },
    2: {
        'id': 2,
        'question_id': 1,
        'answer': 'No',
        'count': 0
    },
    3: {
        'id': 3,
        'question_id': 2,
        'answer': 'Eagles',
        'count': 0
    },
    4: {
        'id': 4,
        'question_id': 2,
        'answer': 'Patriots',
        'count': 0
    },
    5: {
        'id': 5,
        'question_id': 2,
        'answer': 'Seahawks',
        'count': 0
    },
    6: {
        'id': 6,
        'question_id': 2,
        'answer': 'Broncos'
    }
}


class Answer(Resource):
    def get(self, answer_id):
        return answers[answer_id]

    def put(self, answer_id):
        answer = answers[answer_id]
        data = request.get_json()
        values = {k: data.get(k, v) for k, v in answer.items()}
        answers[answer_id].update(values)
        return values

    def delete(self, answer_id):
        values = answers[answer_id]
        del answers[answer_id]
        return values

class Answers(Resource):
    def get(self):
        return answers.values()

    def post(self):
        global answer_id_serial
        answer_id_serial += 1
        data = request.get_json()
        values = {
            'id': answer_id_serial,
            'answer': data['answer'],
            'count': data.get('count', 0),
            'question_id': data['question_id']
        }

        answers[answer_id_serial] = values
        return values


class Question(Resource):
    def get(self, question_id):
        data = questions[question_id].copy()
        data['answers'] = [ans for ans in answers.values() if ans['question_id'] == question_id]
        return data

    def put(self, question_id):
        question = questions[question_id]
        data = request.get_json()
        data.pop('answers', [])
        values = {k: data.get(k, v) for k, v in question.items()}
        questions[question_id].update(values)
        values['answers'] = [ans for ans in answers.values() if ans['question_id'] == question_id]
        return values

    def delete(self, question_id):
        values = questions[question_id]
        del questions[question_id]
        values['answers'] = [ans for ans in answers.values() if ans['question_id'] == question_id]
        return values


class Questions(Resource):
    def get(self):
        output = []
        for question in  questions.values():
            question = question.copy()
            question['answers'] = [ans for ans in answers.values() if ans['question_id'] == question['id']]
            output.append(question)
        return output

    def post(self):
        global question_id_serial
        question_id_serial += 1
        data = request.get_json()
        values = {
            'id': question_id_serial,
            'question': data['question']
        }
        questions[question_id_serial] = values
        return values

api.add_resource(Questions, '/questions')
api.add_resource(Question,  '/questions/<int:question_id>')
api.add_resource(Answers,   '/answers')
api.add_resource(Answer,    '/answers/<int:answer_id>')

@app.route('/')
def show_page():
    return render_template('index.html')

@app.route('/assets/<path:path>')
def get_resource(path):
    mimetypes = {
        '.css': 'text/css',
        '.html': 'text/html',
        '.js': 'application/javascript'
    }

    content = open(path).read()
    return Response(content, mimetype=mimetypes[os.path.splitext(path)[1]])

if __name__ == '__main__':
    app.run(debug=True)

person FullStackDeveloper    schedule 04.07.2017    source источник


Ответы (2)


Это html из render_template('index.html')?

Если это так, вы не можете отобразить шаблон с помощью Flask, а затем попытаться снова отобразить его с помощью Angular.

В основном ваш ng-repeat не работает, Flask не может распознать {{ item }}, отсюда и ошибка.

person henriquesg    schedule 04.07.2017
comment
Это html из render_template('index.html'). Да. Любое предложение решить эту ошибку? Я никогда не использую Flask-REST API. Я работал с ASP.NET REST API. - person FullStackDeveloper; 04.07.2017
comment
Если ваша целевая страница всегда будет возвращать вопросы, а не запрашивать их, вы можете добавить их в контекст при рендеринге Flask. Что-то вроде: render_template('index.html', questions=questions) Затем вы можете использовать синтаксис jinja2 для повторения вопросов в вашем шаблоне: { % for question in questions %} Вы можете прочитать больше здесь: flask.pocoo.org/docs/0.12/quickstart/#rendering-templates - person henriquesg; 04.07.2017
comment
Я провел рефакторинг, чтобы использовать systax jinja2, а также рефакторинг render_template, как вы упомянули, но все еще не работает. - person FullStackDeveloper; 04.07.2017
comment
вы написали что-то вроде: {% for question in questions %} <div> {{ question }} </div> {% endfor %}? посмотрите, поможет ли это: jinja.pocoo.org/docs/2.9/templates - person henriquesg; 04.07.2017
comment
Да. Я это сделал. Я использовал синтаксис jinja2 вместо синтаксиса angularjs. Все еще не работает. Я не знаю, почему мне нужен здесь jinja2 вместо синтаксиса angularjs. - person FullStackDeveloper; 04.07.2017
comment
Трудно сказать, почему это не работает, не глядя на код. В любом случае, этот связанный вопрос может вам помочь: stackoverflow.com/questions/32147748/flask-and-angularjs - person henriquesg; 04.07.2017
comment
Этот пост работает для меня: stackoverflow.com/a/34291267/8229192 я опубликовал свою рабочую версию. Спасибо за ссылку на этот пост. - person FullStackDeveloper; 04.07.2017

После добавления в шаблон {% raw %} и {% endraw %} он теперь работает нормально. я ссылаюсь на этот пост

Я прикрепил рабочий шаблон, надеюсь, он поможет будущим разработчикам, работающим с Flask Restapi и AngularJS:

{% raw %}
<!DOCTYPE html>
<html>

<head>
</head>

<body>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>

    <div ng-app="myApp" ng-controller="myCtrl">

        <h1 ng-repeat="question in questions">{{question.question}}</h1>

    </div>

    <script>
        var app = angular.module('myApp', []);
        app.controller('myCtrl', function ($scope, $http) {
            $http({
                method: "GET",
                url: "http://127.0.0.1:5000/questions"
            }).then(function mySuccess(response) {
                $scope.questions = response.data;
            }, function myError(response) {
                $scope.myWelcome = response.statusText;
            });
        });
    </script>
</body>

</html>
{% endraw %}
person FullStackDeveloper    schedule 04.07.2017