Сериализация и десериализация

Backbone.js предоставляет мощные инструменты для управления данными в приложении через модели и коллекции. Одним из ключевых аспектов работы с моделями является сериализация и десериализация данных, позволяющая преобразовывать объекты JavaScript в формат, пригодный для передачи на сервер, и обратно.


Основные понятия

Сериализация — процесс преобразования объекта модели в стандартный формат данных, обычно JSON, для отправки на сервер. Десериализация — обратный процесс, при котором данные с сервера преобразуются в объекты Backbone.Model или Backbone.Collection.

В Backbone.js эти процессы тесно связаны с методами моделей и коллекций: toJSON и parse.


Метод toJSON

Метод toJSON используется для получения чистого объекта JavaScript, содержащего атрибуты модели. Результат можно напрямую передавать в Backbone.sync, AJAX-запросы или сохранять локально.

var Book = Backbone.Model.extend({
    defaults: {
        title: '',
        author: '',
        year: null
    }
});

var myBook = new Book({ title: '1984', author: 'George Orwell', year: 1949 });
console.log(myBook.toJSON());
// { title: '1984', author: 'George Orwell', year: 1949 }

Ключевые особенности toJSON:

  • Возвращает глубокую копию атрибутов модели.
  • Можно переопределить для кастомной сериализации:
var Book = Backbone.Model.extend({
    toJSON: function() {
        var attrs = _.clone(this.attributes);
        attrs.summary = `${attrs.title} by ${attrs.author}`;
        return attrs;
    }
});

console.log(myBook.toJSON());
// { title: '1984', author: 'George Orwell', year: 1949, summary: '1984 by George Orwell' }

Метод parse

Метод parse отвечает за десериализацию данных, полученных с сервера. Backbone вызывает его автоматически при инициализации модели или при использовании метода fetch.

var Book = Backbone.Model.extend({
    parse: function(response) {
        response.title = response.name;
        delete response.name;
        return response;
    }
});

var serverResponse = { name: 'Brave New World', author: 'Aldous Huxley', year: 1932 };
var book = new Book(serverResponse, { parse: true });
console.log(book.toJSON());
// { title: 'Brave New World', author: 'Aldous Huxley', year: 1932 }

Особенности parse:

  • Позволяет адаптировать формат данных сервера под внутреннюю структуру модели.
  • Используется и при работе с коллекциями, чтобы корректно создать экземпляры моделей.

Сериализация и коллекции

Коллекции в Backbone.js предоставляют метод toJSON, который автоматически сериализует все модели внутри коллекции:

var Library = Backbone.Collection.extend({ model: Book });

var library = new Library([
    { title: '1984', author: 'George Orwell' },
    { title: 'Brave New World', author: 'Aldous Huxley' }
]);

console.log(library.toJSON());
// [
//   { title: '1984', author: 'George Orwell' },
//   { title: 'Brave New World', author: 'Aldous Huxley' }
// ]

Для десериализации коллекции используется parse, который должен возвращать массив объектов для создания моделей:

var serverData = [
    { name: 'Fahrenheit 451', author: 'Ray Bradbury' },
    { name: 'Animal Farm', author: 'George Orwell' }
];

var Library = Backbone.Collection.extend({
    model: Book,
    parse: function(response) {
        return response.map(function(item) {
            item.title = item.name;
            delete item.name;
            return item;
        });
    }
});

var library = new Library(serverData, { parse: true });
console.log(library.toJSON());
// [
//   { title: 'Fahrenheit 451', author: 'Ray Bradbury' },
//   { title: 'Animal Farm', author: 'George Orwell' }
// ]

Пользовательские стратегии сериализации

Иногда требуется изменять структуру данных перед отправкой на сервер. Для этого можно переопределять toJSON:

var Book = Backbone.Model.extend({
    toJSON: function() {
        return {
            book_name: this.get('title'),
            author_name: this.get('author')
        };
    }
});

var myBook = new Book({ title: '1984', author: 'George Orwell' });
console.log(JSON.stringify(myBook.toJSON()));
// {"book_name":"1984","author_name":"George Orwell"}

Это особенно важно, если сервер ожидает специфический формат данных или дополнительные поля.


Интеграция с Backbone.sync

Методы сериализации и десериализации тесно связаны с Backbone.sync, который отвечает за CRUD-операции с сервером. Backbone автоматически использует:

  • toJSON при отправке данных (create, update).
  • parse при получении данных (fetch).
myBook.save();  // toJSON используется для отправки
myBook.fetch(); // parse используется для обработки ответа

При необходимости можно комбинировать кастомные parse и toJSON для сложных структур и вложенных объектов.


Работа с вложенными моделями и коллекциями

Для сериализации и десериализации сложных объектов с вложенными моделями рекомендуется:

  • Внутри toJSON вызывать toJSON для вложенных объектов.
  • В parse обрабатывать вложенные структуры для правильного создания экземпляров моделей или коллекций.
var Chapter = Backbone.Model.extend({});
var Book = Backbone.Model.extend({
    defaults: { chapters: null },
    initialize: function() {
        this.set('chapters', new Backbone.Collection(this.get('chapters'), { model: Chapter }));
    },
    toJSON: function() {
        var json = _.clone(this.attributes);
        json.chapters = this.get('chapters').toJSON();
        return json;
    },
    parse: function(response) {
        if (response.chapters) {
            response.chapters = new Backbone.Collection(response.chapters, { model: Chapter });
        }
        return response;
    }
});

Такой подход позволяет корректно сериализовать и десериализовать сложные объекты с вложенными данными.


Ключевые моменты

  • toJSON — для преобразования модели или коллекции в объект JavaScript.
  • parse — для обработки данных, полученных с сервера.
  • Коллекции автоматически применяют toJSON и parse к каждой модели.
  • Пользовательская сериализация позволяет адаптировать формат данных под требования сервера.
  • Для вложенных структур необходимо явно обрабатывать вложенные модели и коллекции в toJSON и parse.

Сочетание этих инструментов обеспечивает гибкое управление данными, облегчает интеграцию с RESTful API и поддерживает чистую архитектуру приложений на Backbone.js.