Backbone.js изначально проектировался как минималистичный
MVC-фреймворк, ориентированный на работу с данными, получаемыми от
сервера. В основе этой работы лежит строгая модель обмена данными между
клиентом и сервером, где Backbone берет на себя синхронизацию,
сериализацию и интерпретацию различных форматов данных. Ключевыми
элементами здесь выступают Model, Collection и
механизм sync.
Backbone по умолчанию ориентирован на формат JSON, однако архитектура фреймворка позволяет адаптировать его для работы с любыми другими форматами — XML, FormData, URL-encoded, бинарными структурами и даже нестандартными API.
Каждая модель Backbone хранит данные во внутреннем объекте
attributes. Метод toJSON() отвечает за
преобразование этих данных в формат, пригодный для отправки на
сервер.
var User = Backbone.Model.extend({
defaults: {
name: '',
age: 0
}
});
var user = new User({ name: 'Alex', age: 30 });
user.toJSON();
// { name: "Alex", age: 30 }
toJSON() используется автоматически при вызове
save(), create() и других методов, связанных с
синхронизацией. Переопределение этого метода позволяет управлять
структурой данных, отправляемых на сервер.
toJSON: function () {
var attrs = _.clone(this.attributes);
delete attrs.internalFlag;
return attrs;
}
parseМетод parse используется для преобразования данных,
полученных от сервера, в структуру, понятную модели или коллекции.
var User = Backbone.Model.extend({
parse: function (response) {
return response.data;
}
});
Если сервер возвращает объект вида:
{
"status": "ok",
"data": {
"id": 1,
"name": "Alex"
}
}
то parse позволяет изолировать полезную нагрузку. Этот
механизм критически важен при работе с REST-API, где данные часто
оборачиваются в дополнительные мета-поля.
Для коллекций parse должен возвращать массив
моделей:
var Users = Backbone.Collection.extend({
parse: function (response) {
return response.items;
}
});
Backbone не имеет встроенной поддержки XML, но благодаря
переопределению sync и parse можно
адаптировать работу с таким форматом.
parse: function (xml) {
return {
id: $(xml).find('id').text(),
name: $(xml).find('name').text()
};
}
В этом случае сервер должен возвращать XML, а $.ajax —
корректно его интерпретировать. Backbone не ограничивает формат данных,
а лишь передает результат в parse.
sync и управление форматом запросаBackbone.sync отвечает за отправку HTTP-запросов. По
умолчанию он использует jQuery.ajax и отправляет данные в
формате JSON.
Backbone.sync(method, model, options);
Переопределение sync на уровне модели или глобально
позволяет полностью контролировать формат данных.
Backbone.sync = function (method, model, options) {
options.contentType = 'application/x-www-form-urlencoded';
options.data = $.param(model.toJSON());
return Backbone.ajax(options);
};
Таким образом можно адаптировать Backbone под legacy-API, не поддерживающие JSON.
Для передачи бинарных данных используется объект
FormData. Backbone напрямую его не поддерживает, но легко
интегрируется.
var FileModel = Backbone.Model.extend({
sync: function (method, model, options) {
var formData = new FormData();
formData.append('file', model.get('file'));
options.data = formData;
options.processData = false;
options.contentType = false;
return Backbone.ajax(options);
}
});
Такой подход применяется при загрузке изображений, документов и других файлов без дополнительной сериализации.
Коллекции Backbone также оперируют JSON-данными, но часто сервер возвращает сложные вложенные структуры.
{
"users": [
{ "id": 1, "name": "Alex" },
{ "id": 2, "name": "Maria" }
],
"total": 2
}
var Users = Backbone.Collection.extend({
parse: function (response) {
this.total = response.total;
return response.users;
}
});
Хранение дополнительных данных (например, пагинации) непосредственно в коллекции — распространённая практика при работе с REST-API.
Иногда требуется отправлять данные в формате, отличном от внутреннего представления модели.
var Product = Backbone.Model.extend({
toJSON: function () {
return {
product_name: this.get('name'),
product_price: this.get('price')
};
}
});
Внутри приложения используются одни имена полей, а сервер получает другие. Это позволяет изолировать бизнес-логику клиента от API.
ajax и работа без jQueryBackbone допускает замену Backbone.ajax, что позволяет
использовать альтернативные HTTP-клиенты или Fetch API.
Backbone.ajax = function (options) {
return fetch(options.url, {
method: options.type,
body: options.data
});
};
При этом ответственность за формат данных полностью переходит к разработчику, но сохраняется интерфейс Backbone.
Backbone использует стандартные REST-методы:
GETPOSTPUTDELETEНекоторые серверы требуют альтернативных форматов, например, передачи метода через параметр.
options.data._method = 'PUT';
options.type = 'POST';
Такая адаптация часто применяется при интеграции с серверными фреймворками, не поддерживающими все HTTP-методы.
Метод validate работает с уже разобранными данными, но
его логика часто зависит от формата входных значений.
validate: function (attrs) {
if (!attrs.email) {
return 'Email обязателен';
}
}
Корректная работа parse и toJSON напрямую
влияет на надежность валидации и целостность данных.
Backbone.js не навязывает конкретный формат данных, а предоставляет точки расширения:
toJSON — управление исходящими даннымиparse — разбор входящих данныхsync — контроль транспорта и форматаajax — замена HTTP-клиентаТакая архитектура позволяет использовать Backbone.js как универсальный слой синхронизации данных в приложениях с любыми требованиями к формату и протоколу обмена.