javascript - 在模型级别覆盖 Backbone.sync() 以发送额外的参数?

标签 javascript backbone.js coffeescript

说实话,我一直在尝试覆盖模型的 Backbone 的sync() 方法,我有该函数的签名,并且它被正确触发,但是我不知道该怎么做放入函数体,以便它对 DELETE 进行默认调用,但使用额外的参数。 即。

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.sync,而 Model.sync 只调用 Backbone.sync。这是一个代理功能。这是为了提供一个很好的钩子(Hook)来修改单个模型或从该模型扩展的任何模型的 AJAX 行为。

  • 解决方案 1:将 Global Backbone.sync 覆盖为 JSON.stringify,并在指定要发送的数据后修改 contentType与删除请求。
    • 优点:您可以调用 model.destroy() 并可选择传入 options 参数
  • 解决方案 2 - 重写 Model.sync 方法。
    • 优点:覆盖仅影响单个模型。孤立的更改。
    • 缺点:所有希望删除数据的模型都需要从正确的“基本模型”进行扩展
  • 解决方案 3 - 不要覆盖任何内容,并使用所有 stringifycontentType 内容显式调用 model.sync。
    • 优点:非常独立的更改,不会影响任何其他模型。如果您要与大型代码库集成,这很有用。

[Solution 1] - Global Override of Backbone.sync (this will affect all models)

javacript版本

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 */
    }
});
<小时/>

[Solution 2] - Override Backbone.destroy on a base model and extend other models from that.

覆盖

// 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 */
    }
}); 
<小时/>

[Solution 3] - Call .destroy() with correct parameters.

如果通过销毁请求发送数据是一件孤立的事情,那么这是一个足够的解决方案。

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

javascript 版本/用法

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

“问题”(涉及 Backbone,而非解决方案):

Backbone.js 假设 ( view source ) 删除请求具有数据负载。

// 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

关于javascript - 在模型级别覆盖 Backbone.sync() 以发送额外的参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16472593/

相关文章:

javascript - 如何在主干中动态生成的按钮上绑定(bind)事件?

javascript - 如何在分配给数组索引的对象上调用方法?

javascript - 获取 'Uncaught TypeError: $(...).timeago is not a function'

javascript - jQuery:在成功/错误中使用延迟对象(ajaxSetup 选项)

javascript - 奇怪的 Firefox SWFObject 显示问题

javascript - 向 Backbone 模型的各个属性添加值

javascript - 从 Backbone.js 中的集合中删除多个元素

javascript - 无法在文件外访问 coffeescript 函数

javascript - Backbone Coffeescript super 渲染

javascript - 我们可以判断用户是否取消了浏览器文件上传吗?