Knockout.js предоставляет мощный инструмент для работы с двусторонним связыванием данных через observables. Одной из ключевых библиотек для автоматизации процесса связывания является Knockout Mapping, позволяющая преобразовывать обычные JavaScript-объекты в observables и обратно без необходимости ручного объявления каждого свойства.
Для использования Knockout Mapping требуется подключить основной Knockout.js и расширение mapping:
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.5.1/knockout.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.4.1/knockout.mapping.js"></script>
После этого доступны глобальные методы ko.mapping.fromJS
и ko.mapping.toJS.
Метод ko.mapping.fromJS позволяет автоматически
преобразовать обычный объект в объект, где все свойства
являются observables:
var data = {
name: "Иван",
age: 30,
address: {
city: "Москва",
street: "Тверская"
}
};
var viewModel = ko.mapping.fromJS(data);
console.log(viewModel.name()); // Иван
console.log(viewModel.address.city()); // Москва
Особенности:
observableArray, позволяя
отслеживать изменения элементов и их добавление/удаление.Knockout Mapping поддерживает настройку отображения
через объект mapping, где можно задать правила для
отдельных свойств:
var mapping = {
'age': {
create: function(options) {
return ko.observable(options.data + 5); // увеличиваем возраст на 5 лет
}
},
'address': {
update: function(options) {
return ko.observable(options.data.city.toUpperCase());
}
}
};
var viewModel = ko.mapping.fromJS(data, mapping);
console.log(viewModel.age()); // 35
console.log(viewModel.address()); // МОСКВА
Ключевые моменты:
create — вызывается при создании нового
observable.update — вызывается при обновлении существующего
observable.key — позволяет задать уникальный идентификатор для
элементов массива.Метод ko.mapping.toJS используется для преобразования
observables обратно в обычные объекты:
var plainData = ko.mapping.toJS(viewModel);
console.log(plainData);
// {
// name: "Иван",
// age: 35,
// address: "МОСКВА"
// }
Также существует метод ko.mapping.toJSON, который сразу
возвращает JSON-строку:
var jsonData = ko.mapping.toJSON(viewModel);
console.log(jsonData);
// {"name":"Иван","age":35,"address":"МОСКВА"}
Knockout Mapping особенно полезен для массивов объектов:
var data = [
{ name: "Иван", age: 30 },
{ name: "Мария", age: 25 }
];
var viewModel = ko.mapping.fromJS(data);
viewModel.push({ name: "Алексей", age: 40 });
console.log(viewModel()[2].name()); // Алексей
Особенности работы с массивами:
push, pop,
splice) полностью совместимы с observableArray.key, чтобы корректно обновлять
массив при получении новых данных с сервера.var mapping = {
'items': {
key: function(data) {
return ko.utils.unwrapObservable(data.id);
},
create: function(options) {
return new ItemModel(options.data);
}
}
};
function ItemModel(data) {
this.id = ko.observable(data.id);
this.name = ko.observable(data.name);
}
Такой подход позволяет:
ko.mapping.fromJS для
инициализации ViewModel при получении данных с
сервера.mapping options для контроля преобразований и
создания кастомных observable.key, чтобы избежать
пересоздания элементов и сохранить состояние.ko.mapping.toJS
или ko.mapping.toJSON для получения чистого объекта или
JSON.Knockout Mapping позволяет значительно сократить количество ручного кода, автоматизируя процесс связывания данных и упрощая работу с динамическими объектами и массивами в приложениях Knockout.js.