Knockout.js основан на концепции Model-View-ViewModel (MVVM), где основной акцент сделан на декларативное связывание данных. Это позволяет отделить представление (HTML) от логики приложения (JavaScript) и управлять обновлением интерфейса без прямого манипулирования DOM.
Декларативное связывание реализуется через data-bind атрибут в HTML. Внутри него указываются инструкции, которые связывают элементы DOM с наблюдаемыми свойствами ViewModel.
Пример базового связывания:
<input type="text" data-bind="value: userName" />
<p data-bind="text: userName"></p>
var viewModel = {
userName: ko.observable("Иван")
};
ko.applyBindings(viewModel);
Ключевые моменты:
ko.observable создаёт наблюдаемое свойство, которое
автоматически уведомляет подписчиков об изменениях.data-bind описывает, какое свойство ViewModel
связано с элементом и каким образом.Knockout поддерживает несколько категорий связывания:
Value bindings Связывает значения элементов формы с данными ViewModel:
<input data-bind="value: age" />Text и HTML bindings Отображают данные в тексте или как HTML:
<span data-bind="text: userName"></span>
<div data-bind="html: userDescription"></div>Visible и Hidden bindings Управляют видимостью элементов:
<div data-bind="visible: isLoggedIn"></div>Checked bindings Связывают состояние чекбоксов и радио-кнопок с наблюдаемыми:
<input type="checkbox" data-bind="checked: isSubscribed" />Enable/Disable bindings Включение или отключение элементов управления:
<button data-bind="enable: canSubmit">Отправить</button>Options и Selected bindings Работа с выпадающими списками и выбором:
<select data-bind="options: countries, value: selectedCountry"></select>Knockout позволяет создавать комплексные связывания, комбинируя несколько привязок через запятую:
<input type="text" data-bind="value: userName, enable: isEditable, valueUpdate: 'afterkeydown'" />
valueUpdate позволяет контролировать момент обновления
observable.ko.computed создаёт вычисляемые наблюдаемые
свойства, которые автоматически пересчитываются при изменении
зависимостей:
var viewModel = {
firstName: ko.observable("Иван"),
lastName: ko.observable("Петров"),
fullName: ko.computed(function() {
return this.firstName() + " " + this.lastName();
}, this)
};
<p data-bind="text: fullName"></p>
fullName обновляется автоматически
при изменении firstName или lastName.Для работы с массивами используется foreach:
var viewModel = {
tasks: ko.observableArray([
{ name: "Сделать домашку" },
{ name: "Прочитать книгу" }
])
};
<ul data-bind="foreach: tasks">
<li data-bind="text: name"></li>
</ul>
ko.observableArray обеспечивает реактивность при
добавлении, удалении или изменении элементов массива.push, pop,
remove, sort, которые автоматически обновляют
представление.Knockout позволяет создавать собственные привязки через
ko.bindingHandlers:
ko.bindingHandlers.colorize = {
update: function(element, valueAccessor) {
var color = ko.unwrap(valueAccessor());
element.style.color = color;
}
};
<p data-bind="colorize: favoriteColor">Текст с цветом</p>
valueAccessor() возвращает observable или обычное
значение.ko.unwrap() используется для получения актуального
значения observable.Связывание событий реализуется через event или
специальные биндинги вроде click:
<button data-bind="click: save">Сохранить</button>
var viewModel = {
save: function() {
alert("Данные сохранены!");
}
};
addEventListener.Knockout поддерживает условное и динамическое управление
элементами через if, with и
template:
<div data-bind="if: isLoggedIn">
<p>Привет, <span data-bind="text: userName"></span>!</p>
</div>
<div data-bind="with: currentTask">
<h3 data-bind="text: title"></h3>
</div>
if полностью удаляет или добавляет элемент в DOM в
зависимости от условия.with позволяет использовать вложенные объекты как
контекст для биндингов.template обеспечивает повторное использование
HTML-шаблонов с реактивными данными.Декларативное связывание в Knockout.js формирует ядро реактивной архитектуры, позволяя строить сложные интерфейсы с минимальным количеством кода и высокой поддерживаемостью.