Ответ 1
update: KO теперь поддерживает контекстную переменную $index
, которую вы можете использовать в параметре foreach
(или template
с параметром foreach
). Документы: 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>
Изменить: в наши дни я предпочитаю создавать подписку на мой наблюдаемый массив, который должен пройти один проход через массив и создать/установить индекс, наблюдаемый в элементе. Например:
//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/
или вы можете принять эту идею и расширить наблюдаемые массивы, чтобы обеспечить функцию indexed
, которая позволит вам установить это, просто позвонив myObservableArray.indexed()
.
Вот пример: http://jsfiddle.net/rniemeyer/nEgqY/