В Knockout.js foreach является мощным инструментом для
работы с коллекциями данных в представлении. Она позволяет динамически
отображать списки элементов на основе наблюдаемых массивов
(observableArray) и автоматически обновлять DOM при
изменении коллекции.
Привязка foreach применяется к элементу HTML и ожидает
массив или наблюдаемый массив в качестве источника данных. Каждый
элемент массива становится контекстом для вложенной разметки. При
изменении массива Knockout автоматически управляет добавлением,
удалением и обновлением соответствующих элементов DOM.
<ul data-bind="foreach: items">
<li data-bind="text: name"></li>
</ul>
function ViewModel() {
this.items = ko.observableArray([
{ name: 'Элемент 1' },
{ name: 'Элемент 2' },
{ name: 'Элемент 3' }
]);
}
ko.applyBindings(new ViewModel());
В этом примере каждый объект в items представлен
элементом <li> с текстом, соответствующим свойству
name. Любые изменения в массиве автоматически отразятся в
списке.
Привязка foreach создает новый контекст данных для
каждого элемента. Внутри него доступны все стандартные контексты
Knockout: $data, $index, $parent,
$parents, $root.
<ul data-bind="foreach: items">
<li>
<span data-bind="text: $index"></span>:
<span data-bind="text: name"></span>
<ul data-bind="foreach: children">
<li data-bind="text: $data"></li>
</ul>
</li>
</ul>
function ViewModel() {
this.items = ko.observableArray([
{ name: 'Элемент 1', children: ['Подэлемент 1', 'Подэлемент 2'] },
{ name: 'Элемент 2', children: ['Подэлемент 3'] }
]);
}
ko.applyBindings(new ViewModel());
Использование $index позволяет получить текущий индекс
элемента, а $parent предоставляет доступ к родительскому
контексту при вложенных коллекциях.
observableArray предоставляет методы для добавления,
удаления и обновления элементов, что непосредственно влияет на
отображение:
push(item) — добавление элемента в конец массива.pop() — удаление последнего элемента.unshift(item) — добавление элемента в начало
массива.shift() — удаление первого элемента.remove(predicate) — удаление элементов, удовлетворяющих
условию.replace(oldItem, newItem) — замена элемента.Пример:
function ViewModel() {
this.items = ko.observableArray([{ name: 'Элемент 1' }]);
this.addItem = function() {
this.items.push({ name: 'Новый элемент' });
};
this.removeItem = function(item) {
this.items.remove(item);
};
}
<ul data-bind="foreach: items">
<li>
<span data-bind="text: name"></span>
<button data-bind="click: $parent.removeItem">Удалить</button>
</li>
</ul>
<button data-bind="click: addItem">Добавить элемент</button>
Для более сложных коллекций рекомендуется использовать привязку
template совместно с foreach. Это позволяет
отделять разметку элементов списка в отдельный блок, улучшая читаемость
и повторное использование кода.
<script type="text/html" id="itemTemplate">
<li>
<span data-bind="text: name"></span>
</li>
</script>
<ul data-bind="template: { name: 'itemTemplate', foreach: items }"></ul>
Knockout использует стратегию минимальных изменений DOM, добавляя или
удаляя только необходимые элементы при изменении массива. Для больших
коллекций можно использовать track by аналоги через ключи
объектов, чтобы ускорить идентификацию изменений и избежать полной
перерисовки.
this.items = ko.observableArray([
{ id: 1, name: 'Элемент 1' },
{ id: 2, name: 'Элемент 2' }
]);
Использование уникального идентификатора помогает Knockout эффективно обновлять только изменившиеся элементы при массовых операциях.
Привязка foreach в Knockout.js обеспечивает:
Привязка foreach является фундаментальной для построения
динамических интерфейсов с реактивными списками данных, делая работу с
коллекциями простой и безопасной.