Основы привязки

Наблюдаемые объекты

Последнее обновление: 17.05.2016

KnockoutJS отслеживает изменения и при их наличии обновляет связанные компоненты. Но как KnockoutJS узнает, какие части view model были изменены? Для этого свойства модели надо определить как observables или наблюдаемые объекты. Это специальные объекты JavaScript, которые могут извещать подписчиков об изменениях и автоматически отслеживать зависимости.

Для создания наблюдаемых объектов применяется метод ko.observable(), в который передается значение объекта. Рассмотрим на примере:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Observables в KnockoutJS</title>
</head>
<body>
<div>
<p data-bind="text: phoneName"></p>
<p data-bind="text: phoneCompany"></p>
</div>

<script type="text/javascript" src="https://ajax.aspnetcdn.com/ajax/knockout/knockout-3.4.0.js"></script>
<script>
var viewModel = {
    phoneName: ko.observable("Lumia 650"),
    phoneCompany: ko.observable("Microsoft")
};
ko.applyBindings(viewModel);
</script>
</body>
</html>
Observables в KnockoutJS

Здесь во ViewModel определяются два наблюдаемых объекта в виде свойств phoneName и phoneCompany.

Чтобы динамически получить наблюдаемый объект в javascript, надо обратиться к этому объекту как к методу:

var name = viewModel.phoneName();	// Lumia 650
var company = viewModel.phoneCompany();	// Microsoft

Чтобы установить новое значение, надо передать в этот объект новое значение в качестве параметра:

viewModel.phoneName("Lumia 950 XL");

На первый взгляд такое определение ViewModel будет аналогично определению простого объекта:

var viewModel = {
    phoneName: "Lumia 650",
    phoneCompany: "Microsoft"
};

Однако наблюдаемые объекты позволяют также отслеживать изменения. Например, добавим на веб-страницу кнопку, по нажатию которой будем изменять значение наблюдаемого объекта:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Observables в KnockoutJS</title>
</head>
<body>
<div>
<p data-bind="text: phoneName"></p>
<p data-bind="text: phoneCompany"></p>
</div>
<p><button id="changePhoneBtn">Изменить</button></p>
<script type="text/javascript" src="https://ajax.aspnetcdn.com/ajax/knockout/knockout-3.4.0.js"></script>
<script>
var viewModel = {
    phoneName: ko.observable("Lumia 650"),
    phoneCompany: ko.observable("Microsoft")
};
ko.applyBindings(viewModel);

var changePhoneBtn = document.getElementById("changePhoneBtn");
changePhoneBtn.addEventListener("click", function (e) {
	
    viewModel.phoneName("Lumia 950 XL"); // изменяем наблюдаемый объект
});
</script>
</body>
</html>

В итоге при нажатии на кнопку у нас изменится не только сам объект, но и содержимое html-элемента, который привязан к этому объекту:

Отслеживание изменений привязки в Knockout

Если бы мы определили свойства во ViewModel как обычные объекты, то подобная синхронизация значений при их изменении не работала.

Настройка подписки наблюдаемых объектов

С помощью функции subscribe() можно отслеживать изменения в наблюдаемых объектов и выполнять при этом определенные действия. Например, пусть при изменении значения новое значение объекта выводится в диалоговом окне:

viewModel.phoneName.subscribe(function(newValue) {
    alert("Новое значение " + newValue);
});

Функция subscribe принимает функцию обратного вызова, которая вызывается при получении уведомления об изменении наблюдаемого объекта

С помощью метода dispose() в любой момент времени можно прекратить подписку и отменить действие функции subscribe:

var subscription = viewModel.phoneName.subscribe(function(newValue) {
    alert("Новое значение " + newValue);
});
subscription.dispose();
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850