在模型级别重写Backbone.sync()以发送额外的参数

Override Backbone.sync() at Model level to send extra params?

本文关键字:参数 模型 重写 sync Backbone      更新时间:2023-09-26

说实话,我一直在试图覆盖Backbone的sync()方法为一个模型,我有签名的功能在适当的地方,它得到正确触发,但是我不知道什么放在函数体为了让它做一个默认调用DELETE但与额外的参数。ie .

class Master.Models.Member extends Backbone.Model
  urlRoot: '/api/members/'
  sync: (method, model, options) ->
    params = _.clone options
    Backbone.sync method, model, params

我这样称呼它:

......
remove: ->
  @model.destroy
    collective_id: the_id

我的目的是将collective_id参数传递给服务器。但是,即使它在sync()的选项哈希中并且我克隆了它,它也不会使它到达服务器!我如何发送额外的参数到服务器?

(事实上,到达服务器的唯一东西是模型的id)

提前感谢!

当你调用。destroy()、。fetch()或。save()时,它们都会调用Model。它只调用Backbone.sync。它是一个代理函数。这是为了提供一个很好的钩子,用于修改单个模型或从该模型扩展的任何模型的AJAX行为。

  • 方案1:覆盖全局骨干网。当您指定要与删除请求一起发送的数据时,同步到JSON.stringify并修改contentType
    • 优点:您可以调用model.destroy(),并可选择传入options参数
  • 方案2—覆盖模型。同步方法。
      优点:覆盖只影响单个模型。孤立的变化。缺点:所有希望删除带有数据的模型都需要从正确的"基本模型"扩展
  • 解决方案3 -不要覆盖任何内容并显式调用model。与所有stringifycontentType的东西同步。
      优点:非常孤立的变化,不会影响任何其他型号。如果你要集成一个大的代码库,这是很有用的。

[解决方案1]-全局覆盖骨干网。同步(这将影响所有模型)

<

javacript版本/strong>

var oldBackboneSync = Backbone.sync;
Backbone.sync = function( method, model, options ) {
    // delete request WITH data
    if ( method === 'delete' && options.data ) {
        options.data = JSON.stringify(options.data);
        options.contentType = 'application/json';
    } // else, business as usual.
    return oldBackboneSync.apply(this, [method, model, options]);
}
使用

:

var model, SomeModel = Backbone.Model.extend({ /* urlRoot, initialize, etc... */});
model = new SomeModel();
model.destroy({
    data: {
        /* data payload to send with delete request */
    }
});

[解决方案2]-在基本模型上重写Backbone.destroy并从该模型扩展其他模型。

覆盖

// Create your own 'enhanced' model 
Backbone.EnhancedModel = Backbone.Model.extend({
    destroy: function( options ) {
        if ( options.data ) {
            // properly formats data for back-end to parse
            options.data = JSON.stringify(options.data);
        }
        // transform all delete requests to application/json
        options.contentType = 'application/json';
        Backbone.Model.prototype.destroy.call(this, options);
    }
});
使用

var model, SomeModel = Backbone.EnhancedModel.extend({ /* urlRoot, initialize, etc... */})
model = new SomeModel();
SomeModel.destroy({
    data: {
        /* additional data payload */
    }
}); 

[解决方案3]-使用正确的参数调用。destroy()。

如果发送数据与您的销毁请求是一个孤立的事情,那么这是一个适当的解决方案。

当调用model.destroy()时,传递datacontentType选项,如下所示:

/javascript版本使用

var additionalData = { collective_id: 14 };
model.destroy({
    data: JSON.stringify(additionalData),
    contentType: 'application/json'
});

"Problem"(带主干,不带解决方案):

Backbone.js假设(查看源代码)删除请求没有数据负载。

// delete methods are excluded from having their data processed and contentType altered.
if (options.data == null && model && (method === 'create' || method === 'update' || method === 'patch')) {
      params.contentType = 'application/json';
      params.data = JSON.stringify(options.attrs || model.toJSON(options));
}

在他们假设的RESTful API调用中,唯一需要的数据是应该附加到urlRoot属性的ID。

var BookModel = Backbone.Model.extend({
    urlRoot: 'api/book'
});
var book1 = new BookModel({ id: 1 });
book1.destroy()

删除请求将像

这样发送
DELETE => api/book/1
contentType: Content-Type:application/x-www-form-urlencoded; charset=UTF-8

参数需要在options.data中发送,所以尝试:

coffeescript

remove: () ->
  @model.destroy 
    data: JSON.stringify
      collective_id: the_id, 
    contentType: 'application/json'
javascript

remove: function() {
  return this.model.destroy({
    data: JSON.stringify({
      collective_id: the_id
    }),
    contentType: 'application/json'
  });
}