Метод запроса PATCH в Backbone.js - программирование

Метод запроса PATCH в Backbone.js

Каков правильный способ выполнения запроса PATCH при сохранении атрибутов модели в Backbone.js?

4b9b3361

Ответ 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, браузер ваших конечных пользователей не может.