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

Некоторые из моих моделей Backbone всегда должны использовать POST вместо POST для создания и PUT для обновления. Сервер, на котором я сохраняю эти модели, способен поддерживать все остальные глаголы, поэтому использование Backbone.emulateHTTP тоже не идеальное решение.

В настоящее время я отменяю isNew метод для этих моделей и вернуть его true, но это не идеально.

Кроме прямого изменения кода backbone.js, существует ли простой способ достижения этой цели на основе модели от модели? Некоторые из моих моделей могут использовать PUT (они сохраняются на другом сервере, который поддерживает все глаголы, включая PUT), поэтому замена Backbone.sync на тот, который преобразует метод "update" в "create", также не идеален.

5 ответов

Решение

Добавьте синхронизацию (метод, модель, [опции]) непосредственно к вашим моделям, которые необходимо переопределить.

YourModel = Backbone.Model.extend({
  sync: function(method, model, options) {
    //perform the ajax call stuff
  }
}

Вот еще немного информации: http://documentcloud.github.com/backbone/

Для тех, кому нужно принудительно выполнить запрос POST/PUT для экземпляра напрямую:

thing = new ModelThing({ id: 1 });
thing.save({}, { // options
    type: 'post' // or put, whatever you need
})

Короткие и сладкие это сверху

Backbone.emulateHTTP = true;

Это будет использовать Get для Pull и Post для всех нажатий (читай Create, Update, Delete)

Как я это сделал, это переопределить sync() константы выглядит

Models.Thing = Backbone.Model.extend({
    initialize: function() {
        this.url = "/api/thing/" + this.id;
    },
    sync: function(method, model, options) {
        if (method === "read") method = "create";    // turns GET into POST
        return Backbone.sync(method, model, options);
    },
    defaults: {
        ...

Я использовал модификацию ответа Андреса и вместо того, чтобы помнить, чтобы передать опцию { type: 'post' } везде, где я звоню .save() Я вместо этого просто заменил save функция в модели, чтобы она всегда добавляла эту опцию, а затем вызывала базовую реализацию. Это было чище...

module.exports = Backbone.Model.extend({
  idAttribute: 'identifier',
  urlRoot: config.publicEndpoint,

  save: function (attributes, options) {
    // because the 'identifier' field is filled in by the user, Backbone thinks this model is never new. This causes it to always 'put' instead of 'post' on save.
    // overriding save here to always pass the option use post as the HTTP action.
    options = _.extend(options || {}, { type: 'post' });
    return Backbone.Model.prototype.save.call(this, attributes, options);
  }
});
Другие вопросы по тегам