Jinja2:Flask的url_for()结合了Knockout的attr绑定

时间:2013-04-10 16:08:31

标签: python knockout.js flask jinja2

我在一个使用Jinja2作为模板引擎的Web应用程序中一起使用Flask和Knockout。在我的Flask应用程序中,我有两条路线:/accounts//accounts/<int:acc_id>/,它们看起来像这样:

@app.route("/accounts/")
@login_required
def accounts():
    return render_template("accounts.html")


@app.route("/accounts/<int:acc_id>/")
@login_required
def account(acc_id):
    return render_template("account.html",
        account_id=acc_id)

/accounts/路由加载带有Knockout视图模型的HTML页面。视图模型然后AJAX将一个帐户列表加载到observableArray并呈现如下内容:

<!-- ko foreach: accounts -->
    <span data-bind="text: name></span>
<!-- /ko -->

/accounts/<int:acc_id>/路线显示有关单个帐户的信息。

我要做的是使用href在上面的HTML代码段中为每个帐户创建一个url_for()属性,并将帐户的ID作为参数传递。我在使用Knockout模型中的参数对url_for()进行Python调用时遇到了麻烦。

到目前为止,我尝试了几种变体:

将id连接到url_for函数调用:

<a data-bind="attr: { href: '{{ url_for('account', acc_id=' + id() + ' }}'}">
    <span data-bind="text: name"></span>
</a>

这会生成ValueError: invalid literal for int() with base 10: '+ id() +',因为它将对id()的调用读作字符串文字。

在视图模型中创建一个返回url_for字符串的函数:

self.accountUrl = function(account_id) {
    return '{{ url_for("admin.account", acc_id=' + account_id + ') }}';
};

并像这样调用它:

<a data-bind="attr: { href: $root.accountUrl(id()) }">
    <span data-bind="text: name"></span>
</a>

这导致href属性被设置为从accountUrl()返回的字符串文字,即HTML如下所示:

<a href='{{ url_for("account", acc_id=1) }}'>

我觉得我必须在这里忽略一些东西。有什么想法吗?

1 个答案:

答案 0 :(得分:4)

生成HTML时,您的python代码(url_for)在服务器端运行,但Knockout代码在呈现页面时在浏览器中运行。因此,您无法将变量从Knockout传递到python url_for方法。

您可以做的只是生成/accounts/并使用KO构建网址的其余部分:

<a data-bind="attr: { href: '{{ url_for('account') }}' + '/' + id() }">
    <span data-bind="text: name"></span>
</a>