MVVM (Model-View-ViewModel) — это архитектурный паттерн, направленный на разделение логики представления и бизнес-логики приложения. Knockout.js реализует этот паттерн через декларативные биндинги, позволяя создавать динамические интерфейсы с минимальным количеством ручного обновления DOM.
Модель представляет данные приложения и бизнес-логику. В Knockout.js модель обычно реализуется как обычный JavaScript-объект или класс. Ключевая особенность — использование объектов с наблюдаемыми свойствами (observable). Observable свойства автоматически уведомляют все связанные элементы интерфейса об изменениях.
Пример модели:
function Person(name, age) {
this.name = ko.observable(name);
this.age = ko.observable(age);
}
Особенности моделей в Knockout.js:
ko.observable для
примитивных типов и ko.observableArray для массивов.ko.computed позволяет создавать свойства, зависящие от
других наблюдаемых значений.Person.prototype.isAdult = function() {
return ko.computed(() => this.age() >= 18);
};
Представление — это HTML-разметка, которая отображает данные модели. В Knockout.js используется декларативная привязка данных (data-bind). Это позволяет связывать элементы DOM с наблюдаемыми свойствами модели без ручного обновления интерфейса.
Пример биндинга:
<div>
<p>Имя: <span data-bind="text: name"></span></p>
<p>Возраст: <span data-bind="text: age"></span></p>
<p data-bind="visible: isAdult">Совершеннолетний</p>
</div>
Основные типы биндингов:
text — вывод текста.value — связывание с полями ввода.visible и hidden — управление видимостью
элементов.foreach — повторение элементов массива.click и другие события — связывание действий
пользователя с функциями.ViewModel — это слой, который связывает модель и представление. Он хранит состояние, обрабатывает пользовательские действия и вычисляет производные данные. В Knockout.js ViewModel обычно представляет собой объект с наблюдаемыми свойствами и вычисляемыми значениями.
Пример ViewModel:
function AppViewModel() {
this.people = ko.observableArray([
new Person("Алексей", 25),
new Person("Мария", 17)
]);
this.addPerson = function(name, age) {
this.people.push(new Person(name, age));
};
}
ko.applyBindings(new AppViewModel());
Особенности ViewModel:
Knockout.js реализует реактивность через подписку на изменения данных. Observable объекты автоматически уведомляют подписчиков при изменении значений, что позволяет обновлять интерфейс без явного вызова функций рендеринга.
Пример реактивного вычисления:
function AppViewModel() {
this.firstName = ko.observable("Иван");
this.lastName = ko.observable("Иванов");
this.fullName = ko.computed(() => {
return this.firstName() + " " + this.lastName();
});
}
При изменении firstName или lastName,
fullName автоматически обновится, а интерфейс отобразит
новые данные.
Knockout.js поддерживает связывание событий DOM с методами ViewModel. Основные события:
click — вызов функции при клике.submit — обработка отправки формы.event — универсальная привязка для любых событий.Пример:
<button data-bind="click: addPerson.bind($data, 'Новая', 20)">Добавить</button>
При построении крупных приложений важно:
observableArray, чтобы
обеспечить реактивное добавление, удаление и сортировку элементов.Компоненты позволяют инкапсулировать HTML, ViewModel и CSS в отдельные модули. Это упрощает поддержку и повторное использование кода.
Пример регистрации компонента:
ko.components.register('person-card', {
viewModel: function(params) {
this.person = params.person;
},
template: `
<div>
<p data-bind="text: person.name"></p>
<p data-bind="text: person.age"></p>
</div>
`
});
Использование компонента:
<person-card params="person: people()[0]"></person-card>
Knockout.js позволяет создавать интерфейсы, где изменения данных мгновенно отражаются на представлении, а взаимодействие с DOM минимизировано, что делает архитектуру MVVM естественным выбором для динамических веб-приложений.