KnockoutJS: доступ к индексу элемента в массиве из шаблона JavaScript
Я заполняю список из массива, используя KnockoutJS:
<div data-bind:"foreach: list">
<input type="text" data-bind="value: myText" />
</div>
function ViewModel() {
self.list = ko.observableArray([
new listItem("sample text")
]);
};
function listItem (text) {
this.myText = text;
};
Я могу назначить идентификатор для отдельных экземпляров моего ввода, так
<input data-bind="attr: { id: $index } ...
Как мне получить доступ к этому индексу из моей функции listItem? Я хочу быть в состоянии сделать что-то вроде
function listItem (text) {
this.myText = text;
this.index = $index;
};
чтобы использовать это для дальнейшей обработки.
1 ответ
Вы можете создать пользовательскую привязку, которая устанавливает ваше свойство в индекс, это будет выглядеть примерно так:
ko.bindingHandlers.setIndex = {
init: function(element, valueAccessor, allBindings, data, context) {
var prop = valueAccessor();
data[prop] = context.$index;
}
};
Это предполагает, что вы имеете дело с объектами в вашем массиве. Вы бы использовали это как:
<ul data-bind="foreach: items">
<li data-bind="setIndex: 'myIndex', text: name"></li>
</ul>
Итак, это копирует $index
наблюдаемый на вашем объекте с указанным вами именем свойства. Пример: http://jsfiddle.net/rniemeyer/zGmcg/
Другой способ, которым вы можете сделать это вне привязки (это то, как я делал это раньше $index
) подписаться на изменения в observableArray и каждый раз заново заполнять индекс.
Вот как может выглядеть расширение observableArray:
//track an index on items in an observableArray
ko.observableArray.fn.indexed = function(prop) {
prop = prop || 'index';
//whenever the array changes, make one loop to update the index on each
this.subscribe(function(newValue) {
if (newValue) {
var item;
for (var i = 0, j = newValue.length; i < j; i++) {
item = newValue[i];
if (!ko.isObservable(item[prop])) {
item[prop] = ko.observable();
}
item[prop](i);
}
}
});
//initialize the index
this.valueHasMutated();
return this;
};
Вы бы тогда использовали это как:
this.myItems = ko.observableArray().indexed('myIndexProp');
Вот пример: http://jsfiddle.net/rniemeyer/bQD2C/