将模板项绑定到KnockoutJS中数组的索引

时间:2011-05-18 16:09:18

标签: jquery knockout.js

我需要在KnockoutJS模板中根据它们出现在Jquery插件列表中的位置命名<div>'s,如下所示:

<div id="item1">...</div>
<div id="item2">...</div>
<div id="item3">...</div>

有没有办法使用KnockoutJS绑定到数组中项目的索引? 如果我必须使用ROWINDEX将数据添加到数据库中的select上,那将是一种耻辱。

3 个答案:

答案 0 :(得分:21)

更新:KO现在支持$index上下文变量,您可以在foreach(或templateforeach参数)中使用该变量。文档:http://knockoutjs.com/documentation/binding-context.html

如果你可以使用jQuery模板{{each}},那么这样的东西就可以了:

<div data-bind="template: 'allItemsTmpl'"></div>
<script id="allItemsTmpl" type="text/html">
    {{each(i, item) items}}
    <div data-bind="attr: { id: 'item' + i }">
        <input data-bind="value: name" />
    </div>
    {{/each}}
</script>

如果你必须使用foreach选项,那么这样的东西就可以了:

<div data-bind="template: { name: 'itemTmpl', foreach: items }"></div>
<button data-bind="click: addItem">Add Item</button>
<script id="itemTmpl" type="text/html">
    <div data-bind="attr: { id: 'item' + ko.utils.arrayIndexOf(viewModel.items, $data) }">
        <input data-bind="value: name" />
    </div>
</script> 

编辑:这些天我更喜欢创建对我的observableArray的订阅,只需要通过数组一次并在项目上创建/设置索引observable。喜欢:

//attach index to items whenever array changes
viewModel.tasks.subscribe(function() {
    var tasks = this.tasks();
    for (var i = 0, j = tasks.length; i < j; i++) {
       var task = tasks[i];
        if (!task.index) {
           task.index = ko.observable(i);  
        } else {
           task.index(i);   
        }
    }
}, viewModel);

此处示例:http://jsfiddle.net/rniemeyer/CXBFN/

或者您可以采用这个想法并扩展observableArrays以提供indexed函数,该函数允许您通过调用myObservableArray.indexed()来设置它。

以下是一个示例:http://jsfiddle.net/rniemeyer/nEgqY/

答案 1 :(得分:16)

使用Knockout 2.1.0及更高版本会更容易:

<div data-bind="foreach: items">
   <div data-bind="attr: { id : 'item' + $index() }"></div>
</div>

不需要花哨的脚本。

请注意: attr: { id : 'item' + $index }无效。由于$index本身就是一个函数,因此无法添加括号将导致您的id成为'item'和整个函数定义的串联!

答案 2 :(得分:1)

有同样的问题,但使用dependantObservable作为foreach模板的源, 唉ko.utils.arrayIndexOf不起作用......

解决方案:创建了一个函数,该函数重新创建了dependantObservable返回的数组,并简单地将js indexOf函数与Item一起使用:

arrayIndexDO: function (item) {
    var filteredArray = ko.utils.arrayFilter(viewModel.someObservableArray(), function (element) {
        return element.id() == view.selectedId();
    });
    var index = filteredArray.indexOf(item);
    return index;
}

Etvoilà,jQuery tpl中的预期索引。