Как заставить POST-запрос при сохранении модели?
Мне нужно сделать POST для API на стороне сервера. Я должен отправить id
введите тело запроса к серверу.
Я использую модель Backbone. Но, когда я делаю:
myModel.set("id", somevalue)
myModel.save()
Запущенный сетевой запрос: URL/someValue [PUT]
Backbones не делает POST, а PUT и добавляет идентификатор в URL.
Так что я просто хочу передать id
ключ к серверу без замечаний Backbone.
1 ответ
Из документа Backbone:
Backbone предварительно настроен для синхронизации с RESTful API.
[...]
По умолчанию
sync
обработчик отображает CRUD в REST примерно так:
- создать →
POST /collection
- читать →
GET /collection[/id]
- обновить →
PUT /collection/id
- патч →
PATCH /collection/id
- удалить →
DELETE /collection/id
Новая запись не имеет идентификатора, поэтому, если вы передадите ID модели перед ее сохранением, Backbone по умолчанию отправит запрос PUT, потому что думает, что вы хотите сохранить существующую запись.
Как сделать POST-запрос с идентификатором?
Выберите одно из следующих решений.
Придерживайтесь RESTful API
Этот является очевидным. Если можете, придерживайтесь стандарта.
Измените API для обработки запросов PUT/PATCH и используйте POST только при создании. Заставьте конечную точку API взять идентификатор из URL.
Пройти type
вариант 1
Просто и работает очень хорошо для одноразовой ситуации.
Все варианты переданы save
(или же fetch
) переопределяет параметры sync
функция определяет по умолчанию и переходит к jQuery.ajax
функция
позвоночник 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"
имеет имя атрибута идентификатора по умолчанию. Вы можете указать другое имя, переопределив 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
Если вы хотите работать с устаревшим веб-сервером, который не поддерживает стандартный подход REST/HTTP от Backbone, вы можете включить его.
Backbone.emulateHTTP
, Установка этой опции будет подделкойPUT
,PATCH
а такжеDELETE
запросы с HTTPPOST
, установивX-HTTP-Method-Override
заголовок с истинным методом.[...]
Backbone.emulateHTTP = true; model.save(); // POST to "/collection/id", with "_method=PUT" + header.
Не переопределять isNew
Эта модель уже сохранена на сервере? Если модель еще не имеет идентификатора, она считается новой.
Некоторые другие ответы на этом сайте предлагают переопределить isNew
функция Не Функция имеет свою цель, и ее переопределение для принудительной отправки POST-запроса - плохой взлом, а не решение.
isNew
используется внутри, но также может использоваться вашим кодом или другими библиотеками и плагинами Backbone.
1 Хотя я не брал это из-за переполнения стека, это был уже ответ Андреса Торреса Маррокина на похожий вопрос.
2 Взято из ответа Maanas Royy.