Из документа Backbone:
Backbone предварительно настроен для синхронизации с RESTful API.
[...]
Обработчик sync
по умолчанию сопоставляет CRUD с REST следующим образом:
- создать →
POST /collection
- прочитать →
GET /collection[/id]
- обновить →
PUT /collection/id
- исправление →
PATCH /collection/id
- удалить →
DELETE /collection/id
Новая запись не имеет идентификатора, поэтому, если вы укажете идентификатор модели перед ее сохранением, Backbone по умолчанию выполнит запрос PUT, поскольку считает, что вы хотите сохранить существующую запись.
Как сделать POST-запрос с идентификатором?
Выберите одно из следующих решений.
Придерживайтесь RESTful API
Очевидный вариант. Если можете, придерживайтесь стандарта.
Измените API для обработки запросов PUT/PATCH и используйте POST только при создании. Заставьте конечную точку API получать идентификатор из URL-адреса.
Рекомендации по RESTful API
Передайте параметр type
1
Просто и очень хорошо работает в разовой ситуации.
Все параметры, переданные в save
(или fetch
), переопределяют параметры, которые функция sync
определяет по умолчанию, и передаются в функцию jQuery.ajax
а>.
источник Backbone sync
// Make the request, allowing the user to override any Ajax options.
var xhr = options.xhr = Backbone.ajax(_.extend(params, options));
var url = model.url(); // get the url before setting the `id`
model.save({
id: somevalue
}, {
url: url, // fix the url
type: 'POST' // choose the HTTP verb
});
Исправить URL-адрес, который использует модель, просто, у вас также есть несколько вариантов:
- передать параметр
url
(как указано выше)
- переопределить
url
функцию модели
Переопределение функции url
(источник) хорошо работает для ситуация, когда каждый вызов должен использовать определенный URL-адрес без добавленного к нему id
по умолчанию.
var MyModel = Backbone.Model.extend({
url: function() {
return _.result(this, 'urlRoot') ||
_.result(this.collection, 'url') ||
urlError();
}
});
Установите idAttribute
на модель
Это зависит от того, что означает id
, который вы пытаетесь передать в данных.
Базовая модель использует "id"
, имеет имя атрибута id по умолчанию. Вы можете указать другое имя, переопределив свойство idAttribute
модели. Каким бы ни было имя, оно всегда автоматически становится доступным через свойство model.id
.
Теперь, предполагая, что атрибут id
не связан с этой моделью, а настоящее имя атрибута id этой модели похоже на UID
, вы можете изменить idAttribute
модели, чтобы отразить реальное имя атрибута (или это может быть даже строка, которая никогда не будет атрибутом).
var MyModel = Backbone.Model.extend({
idAttribute: 'UID',
});
Теперь атрибут id
не считается идентификатором для текущей модели, а model.isNew()
вернет true
, отправив запрос POST для его создания при сохранении.
Измените поведение функции sync
/save
Если используемый вами API не RESTful, вы можете настроить поведение, переопределив sync
функция. Это можно сделать с моделью или коллекцией или с помощью Backbone.sync
функции, которая по умолчанию используется коллекциями. и модели.
Например, если вы хотите, чтобы каждый запрос использовал POST по умолчанию для класса MyModel
:
var MyModel = Backbone.Model.extend({
sync: function(method, model, options) {
return Backbone.sync.call(this, method, model,
_.extend({ type: 'POST' }, options));
}
});
Вы могли бы сделать что-то подобное только с функцией save
, чтобы позволить fetch
выполнять свой GET
запрос как обычно.
Используйте настройку emulateHTTP
2.
Если вы хотите работать с устаревшим веб-сервером, который не поддерживает стандартный подход Backbone REST/HTTP, вы можете включить Backbone.emulateHTTP
. Установка этого параметра будет подделывать запросы PUT
, PATCH
и DELETE
с HTTP POST
, устанавливая заголовок X-HTTP-Method-Override
с истинным методом.
[...]
Backbone.emulateHTTP = true;
model.save(); // POST to "/collection/id", with "_method=PUT" + header.
Не переопределять isNew
Эта модель уже сохранена на сервере? Если у модели еще нет id, она считается новой.
Некоторые другие ответы на этом сайте предлагают переопределить функцию isNew
. Не. У этой функции есть свое предназначение, и переопределение ее для принудительного POST-запроса — это плохой хак, а не решение.
isNew
используется внутри, но также может использоваться вашим кодом или другими библиотеками и плагинами Backbone.
1 Хотя я не взял это из переполнения стека, это уже был ответ Андреса Торреса Маррокина по похожему вопросу.
2 Взято из ответа Маанаса Роя.
person
Emile Bergeron
schedule
11.12.2016