将反向网址传递给knockout.js模型

时间:2014-08-20 15:07:26

标签: javascript python django url knockout.js

我使用 knockout.js 绑定获得了 django模板,其中列表应该作为一个按钮填充:

<ul data-bind="foreach: items">
   <li data-bind="text: title"><li>
</ul>
<button data-bind="click: fillList">Show</button>

和一些淘汰模型:

function ItemsModel() {
    var self = this;
    self.items = ko.observableArray();

    self.fillList = function() {
        // some download data logic
        ...
    }
}

Functon fillList 从服务器获取数据。它应该向url发送请求。我使用反向网址:

{% url "app.views.get_items" %}

模板生成的网址传递给 ItemsModel 的最佳方式是什么,以便它知道应该从何处获取数据?

将其作为参数传递给模型?

function ItemsModel(url_get_items) {
     ...
}

也许将其作为参数传递给点击事件?

<button data-bind="click: function() { fillList('{% url "app.views.get_items" %}') }">

或者改用提交绑定?

<form action="{% url "app.views.get_items" %}" data-bind="submit: fillList">
    <button type="submit">Show</button>
</form>

还有别的吗?有没有最好的办法?

2 个答案:

答案 0 :(得分:0)

我通常将url放在我在脚本中读取的元素的属性中,并在创建时传递给视图模型。这是一个例子:

<强> HTML

<div id="app" data-url="your/url/here">
    <span data-bind="text: url"></span>
</div>

<强>的Javascript

(function () {
    function ItemsModel(url) {
    var self = this;
        self.items = ko.observableArray();

        // Adding an observable just to prove its accessible here.
        self.url = ko.observable(url);

        self.fillList = function () {
            // some download data logic from url
        }
    }

    var url = document.getElementById('app').getAttribute('data-url');
    console.log(url);
    ko.applyBindings( new ItemsModel(url) ,document.getElementById('app')) ;
}());

这是fiddle

答案 1 :(得分:0)

所以,回答我自己的探索。我找到并成功使用的最佳方法是传递给模型网址对象。通常它看起来像这样:

<script>
    var model = new ItemsModel({
        csrf: '{{ csrf_token }}',
        url: {
            'items': '{% url "items.views.items.api.list" %}',
            ...
            'remove_item': '{% url "items.views.items.api.remove" %}'
        }
    });
    ko.applyBindings(model);
</script>

使用AMD风格有点清洁。您可以在html页面中创建模块,如下所示:

<script>
    define('settings', { 
        csrf: '{{ csrf_token }}',
        url: {
            'items': '{% url "items.views.items.api.list" %}',
            ...
            'remove_item': '{% url "items.views.items.api.remove" %}'
        }
    });
</script>

然后在必需的脚本中引用它:

require(['settings', 'knockout'], function (settings, ko) {
    var model = new ItemsModel(settings);
    ko.applyBindings(model);
});

如果您打算使用r.js,您应该为config中的设置提供空路径,如下所示:

({
    baseUrl: 'items-app',
    out: 'dist/items.js',
    paths: {
        'knockout': 'path/to/knockout',
        'settings': 'empty:',
    }
})

唯一的问题是此方法不适用于带params的网址。最简单的解决方法是使用post或get方法传递所有参数。