Knockout.js — это библиотека для привязки данных в JavaScript, которая позволяет синхронизировать модели данных с интерфейсом пользователя. Одним из ключевых аспектов работы с моделями является способность сериализовать и десериализовать данные, чтобы сохранять их в формате JSON, передавать на сервер или загружать из него.
Сериализация представляет собой процесс преобразования структуры
данных, содержащей observables и observableArrays, в стандартный
JavaScript-объект, который можно безопасно преобразовать в JSON. В
Knockout.js стандартные observables не являются обычными значениями, а
функциями, что делает прямое использование JSON.stringify
неэффективным:
var viewModel = {
name: ko.observable("Иван"),
age: ko.observable(30)
};
JSON.stringify(viewModel); // Результат: {}
В данном примере результат пустой объект, потому что observables не перечисляются как обычные свойства. Для корректной сериализации необходимо использовать функцию ko.toJS или ko.toJSON.
ko.toJS рекурсивно преобразует observables в обычные
объекты Jav * aScript:
var plainObject = ko.toJS(viewModel);
console.log(plainObject);
// { name: "Иван", age: 30 }
Особенности использования ko.toJS:
ko.toJSON является оберткой над ko.toJS,
которая сразу возвращает JSON-строку:
var jsonString = ko.toJSON(viewModel);
console.log(jsonString);
// '{"name":"Иван","age":30}'
Преимущества:
replacer и space,
как стандартный JSON.stringify:var formattedJson = ko.toJSON(viewModel, null, 2);
console.log(formattedJson);
Десериализация — это процесс преобразования JSON-строки или обычного объекта в рабочую модель Knockout.js с observables:
var jsonData = '{"name":"Петр","age":25}';
var parsedData = JSON.parse(jsonData);
var viewModel = {
name: ko.observable(parsedData.name),
age: ko.observable(parsedData.age)
};
Для сложных моделей с вложенными объектами и массивами создаются функции-конструкторы:
function Person(data) {
this.name = ko.observable(data.name);
this.age = ko.observable(data.age);
this.friends = ko.observableArray(
data.friends ? data.friends.map(friend => new Person(friend)) : []
);
}
var data = {
name: "Анна",
age: 28,
friends: [
{ name: "Мария", age: 27 },
{ name: "Сергей", age: 30 }
]
};
var person = new Person(data);
При работе с крупными объектами или массивами важно учитывать
производительность. Использование ko.mapping облегчает
процесс:
var mapping = {
'friends': {
create: function(options) {
return new Person(options.data);
}
}
};
var mappedPerson = ko.mapping.fromJS(data, mapping);
Особенности:
Для обратного преобразования используется
ko.mapping.toJS или ko.mapping.toJSON:
var plainData = ko.mapping.toJS(mappedPerson);
var jsonData = ko.mapping.toJSON(mappedPerson);
| Метод | Тип возврата | Рекурсивность | Применение |
|---|---|---|---|
ko.toJS |
JS-объект | Да | Локальная обработка данных |
ko.toJSON |
JSON-строка | Да | Отправка данных на сервер |
ko.mapping.fromJS |
Knockout-модель | Да | Автоматическая генерация observables |
ko.mapping.toJS |
JS-объект | Да | Получение чистого объекта из модели |
ko.mapping.toJSON |
JSON-строка | Да | Отправка сложных моделей на сервер |
ko.toJS и
ko.toJSON.ko.mapping.// Отправка данных на сервер
$.ajax({
url: '/api/person',
type: 'POST',
data: ko.toJSON(person),
contentType: 'application/json',
success: function(response) {
console.log('Данные успешно отправлены');
}
});
// Получение данных с сервера и создание модели
$.getJSON('/api/person/1', function(data) {
var person = ko.mapping.fromJS(data);
});
Эти подходы обеспечивают стабильное хранение и передачу данных между клиентом и сервером, сохраняя реактивность модели и позволяя эффективно управлять изменениями в интерфейсе.