我认为问题在于数据和模板信息的分离。
如果您使用的是敲除,那么您通常是在服务器上生成数据,并将其作为 json 数据发送到客户端的模板渲染中。
该url_for
函数是服务器端 函数,因此您不能在客户端模板中的客户端上运行它。
正如@Miguel 的回答一样,最简单/最好的方法是在服务器上生成 url,作为数据的一部分,而不是模板的一部分。
因此,您用于生成数据的 app.route 可能是:
@app.route('/posts/')
def posts_list():
posts = []
for post in get_posts(): #however you actually get your posts from your db
author = get_author(post.author) #however you actually get author info
posts.append(
{"id": post.id,
"title":post.title,
"author_name": author["display_name"],
"author_uri": url_for('user_profile', author["name"], author["id"]),
"content": post.content})
return jsonify({"posts": posts})
管他呢。您正在服务器端生成所有帖子数据,因此您可以访问 url_for 函数。然后客户端只需要渲染纯数据:
<div data-bind="foreach: posts">
<div class="post">
<div data-bind="text: content" class="content"></div>
<div class="author_info">
<a data-bind="attr: { href: author_uri }, text: author_name"></a>
</div>
</div>
</div> <!-- posts -->
然后在 HTML app.route 中,在完成所有纯敲除模板之后,初始化敲除视图,然后从 posts json 路由请求数据:
<!-- at the end of your HTML page/view, after including your models, and libs -->
<script type="text/javascript">
// autogenerated:
POSTS_URL="{{ url_for('posts_list') }}";
// initialise views:
postsview = new PostsView( data );
ko.applyBindings(posts);
// get initial data:
$.getJSON(POSTS_URL, function (data) {
// we've just got data sent to us from the posts_list route!
postsview.posts(data.posts);
});
</script>
如果您尝试将 jinja 模板代码(服务器端)与淘汰模板代码(客户端)混合,那么您将遇到问题。您需要将它们视为完全独立的系统,并来回传递纯数据(通常是 JSON)。
或者,您可以将数据直接嵌入到您的页面中,而不是发出单独的异步请求。但同样,请记住让您的淘汰代码完全没有 jinja 模板,然后在页面末尾,而不是执行 $.getJSON 的东西,您只需执行以下操作:
<script type="text/javascript">
POSTS_DATA={{ posts |tojson|safe }};
posts = new PostsView( POSTS_DATA );
ko.applyBindings(posts);
</script>
如果您以这种方式分离数据,则更容易推理,而且如果稍后您决定切换到不同的 javascript 引擎,您也可以这样做,因为数据包含您需要的一切。或者,如果您决定重新编写 python 引擎,或者如果您想制作一个原生应用程序,或者其他什么。
我希望这有帮助!