Каков правильный способ выполнения запроса PATCH
при сохранении атрибутов модели в Backbone.js?
Метод запроса PATCH в Backbone.js
Ответ 1
Как и в Backbone.js v0.9.9, вы можете просто передать { patch: true }
в save()
.
Подробнее: http://backbonejs.org/#changelog
Ответ 2
В дополнение к ответу Джеймса Кропчоса я хочу добавить следующее, потому что это украло у меня несколько часов и, возможно, поможет кому-то еще:
Если вы используете model.save(attributesToPatchObject,{patch: true})
как это возможно, начиная с магистрали v.0.9.9, как указано в ответе Джеймса Кропхоса, вы можете задаться вопросом, как определить, какие атрибуты изменились со времени последнего вызова model.save()
чтобы передать их в качестве attributesToPatchObject
который является первым аргументом model.save()
(или model.fetch()
если вы не сохранили модель в последнее время).
Сам Backbone не отслеживал эти атрибуты. Я думал, что метод model.changedAttributes()
мог бы соответствовать, но, как говорит док-документ, этот метод возвращает
хэш только атрибутов модели, которые изменились с момента последнего набора, или false, если их нет
Так что этот метод не подходит для этой необходимости. После некоторых исследований я обнаружил, что сама магистраль не отслеживает несохраненные атрибуты (я знаю, что это не блестящая находка, если бы я внимательно прочитал документы).
Я обнаружил, что backbone.trackit - это плагин для магистрали, который точно добавляет необходимую функцию в магистраль, добавляя метод unsavedAttributes()
в модель. Документация по backbone.trackit говорит об этом методе:
Симметричен Backbone model.changedAttributes(), за исключением того, что он возвращает хэш атрибутов модели, которые изменились с момента последнего сохранения, или false, если их нет. Как и changeAttributes, можно передавать хеш внешних атрибутов, возвращая атрибуты этого хеша, которые отличаются от модели.
Это работает так:
//fetch an existing model from server
model.fetch({
success : function(model, respose, options) {
//tell backbone.trackit to track unsaved Attributes
model.startTracking();
}
});
//now some changes to the model happen
model.set("someProperty", "someValue");
/* save the model to server using the PATCH-Method
and only send the unsaved Attributes;
in this case only "someProperty" is sent
*/
model.save(model.unsavedAttributes(), {patch: true});
Так как unsavedAttributes()
возвращает false, если нет несохраненных атрибутов, вы можете дополнительно обернуть свой оператор save()
в условие if, которое проверяет, возвращает ли unsavedAttributes()
что-то другое, чем false, и выполняет ваш PATCH-запрос только в случае необходимости ( потому что что-то изменилось).
ПРИМЕЧАНИЕ. Вам не нужно было вызывать fetch()
чтобы использовать startTracking()
поэтому вы можете использовать этот метод даже с вновь созданными моделями (model.isNew()
возвращает true для этой модели), если для этого есть сценарий использования.
Надежды это может сэкономить кому-то немного времени на исследования.
Ответ 3
Вам придется переопределить Backbone.sync
и расширить существующий метод mapper
var methodMap = {
'create': 'POST',
'update': 'PUT',
'delete': 'DELETE',
'read': 'GET',
'patch': 'PATCH'
};
вам нужно будет создать свой собственный метод патча на модели типа
Backbone.Model.prototype.patch = function(options)
{
// some code here that checks what attributes have changed since last save
var xhr = (this.sync || Backbone.sync).call(this, 'patch', this, options);
return xhr;
}
Я уверен, что вы можете расширить Backbone дальше, включив OPTIONS
и HEAD
, если вам нужно
Обратите внимание, что даже через jQuery поддерживаются методы PATCH, OPTIONS и HEAD, браузер ваших конечных пользователей не может.