Knockout.js предоставляет мощный механизм привязки данных и динамического обновления пользовательского интерфейса. Одним из ключевых элементов этой системы являются шаблоны (templates), которые позволяют повторно использовать HTML-код, динамически отображать коллекции и управлять структурой интерфейса на основе данных.
Шаблон в Knockout.js — это фрагмент HTML, который связывается с определённой моделью данных. С помощью шаблонов можно:
В Knockout.js шаблоны обычно определяются двумя способами:
<script> с
атрибутом type="text/html":<script type="text/html" id="item-template">
<div class="item">
<h3 data-bind="text: name"></h3>
<p data-bind="text: description"></p>
</div>
</script>
data-bind="template: {...}":<div data-bind="template: { name: 'item-template', foreach: items }"></div>
Для работы с шаблонами используется специальная привязка
template. Основные варианты её использования:
name — имя шаблона. Указывается, если шаблон определён
через <script> с id.foreach — массив объектов, для каждого из которых будет
создана копия шаблона.data — одиночный объект, с которым будет связана
область шаблона.if / ifnot — условное отображение
шаблона.Пример использования foreach:
function AppViewModel() {
this.items = ko.observableArray([
{ name: 'Элемент 1', description: 'Описание 1' },
{ name: 'Элемент 2', description: 'Описание 2' }
]);
}
ko.applyBindings(new AppViewModel());
<div data-bind="template: { name: 'item-template', foreach: items }"></div>
Каждый объект массива items будет отображён с
использованием шаблона item-template.
Knockout.js поддерживает вложенные шаблоны, что позволяет создавать сложные структуры интерфейса без дублирования кода. Например:
<script type="text/html" id="category-template">
<div class="category">
<h2 data-bind="text: title"></h2>
<div data-bind="template: { name: 'item-template', foreach: items }"></div>
</div>
</script>
function Category(title, items) {
this.title = title;
this.items = ko.observableArray(items);
}
function AppViewModel() {
this.categories = ko.observableArray([
new Category('Категория 1', [{ name: 'Элемент A', description: 'Описание A' }]),
new Category('Категория 2', [{ name: 'Элемент B', description: 'Описание B' }])
]);
}
ko.applyBindings(new AppViewModel());
<div data-bind="template: { name: 'category-template', foreach: categories }"></div>
Вложенные шаблоны позволяют эффективно разделять логику представления по компонентам, делая код более читаемым и поддерживаемым.
Шаблоны можно настраивать с помощью параметров:
as — задаёт имя переменной, которая будет
использоваться внутри шаблона вместо $data.afterRender — функция, вызываемая после отрисовки
шаблона. Используется для интеграции с плагинами или выполнения
дополнительных действий.templateEngine — позволяет указать кастомный движок
шаблонов (например, jQuery.tmpl).Пример использования параметра as:
<div data-bind="template: { name: 'item-template', foreach: items, as: 'item' }"></div>
Внутри шаблона вместо $data можно использовать
item:
<div class="item">
<h3 data-bind="text: item.name"></h3>
<p data-bind="text: item.description"></p>
</div>
Knockout.js позволяет менять шаблон в зависимости от данных. Это
реализуется через привязку name с вычисляемым
значением:
function AppViewModel() {
this.currentTemplate = ko.observable('template1');
this.switchTemplate = function() {
this.currentTemplate(this.currentTemplate() === 'template1' ? 'template2' : 'template1');
}.bind(this);
}
<div data-bind="template: { name: currentTemplate, data: someData }"></div>
<button data-bind="click: switchTemplate">Сменить шаблон</button>
Такой подход позволяет создавать интерфейсы с динамически изменяемым контентом, минимизируя дублирование HTML.
Для коллекций часто используют сочетание foreach и
шаблонов для упрощения управления списками. Это особенно удобно при
работе с динамическими массивами observable:
this.items.push({ name: 'Новый элемент', description: 'Новое описание' });
После добавления элемента шаблон автоматически обновляет интерфейс,
благодаря реактивной природе observableArray.
as,
afterRender, templateEngine) предоставляют
гибкость при интеграции с внешними библиотеками или при специфических
требованиях к отображению.Шаблоны в Knockout.js формируют основу эффективной работы с динамическим пользовательским интерфейсом, обеспечивая лёгкую реактивность и возможность масштабирования кода без потери структуры и читаемости.