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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16472593/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 04:49:23  来源:igfitidea点击:

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

javascriptbackbone.jscoffeescript

提问by jlstr

To be quite honest I'm stuck trying to override Backbone's sync() method for a Model, I have the signature for the function in place, and it gets triggered correctly, but I don't know what to put in the function bodyin order for it to make a default call to DELETE but with extra arguments. ie.

老实说,我一直在尝试覆盖模型的 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

I call it like this:

我这样称呼它:

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

My intention there, is to pass the collective_idparam you see there to the server. But even though it's inside the options hash for sync() and I clone it, It won't make it to the server!How can I send that extra param to the server?

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

(As it is, the only thing that reaches the server is the Model's id)

(实际上,到达服务器的唯一内容是模型的 id)

Thanks in advance!

提前致谢!

回答by Cory Danielson

When you call .destroy(), .fetch() or .save() they all call Model.sync which only calls Backbone.sync. It's a proxy function. This is intended to provide a nice hook for modifying the AJAX behavior of a single model or any models that extend from that model.

当您调用 .destroy()、.fetch() 或 .save() 时,它们都调用 Model.sync,后者只调用 Backbone.sync。这是一个代理功能。这旨在为修改单个模型或从该模型扩展的任何模型的 AJAX 行为提供一个很好的钩子。

  • Solution 1: Override the Global Backbone.sync to JSON.stringifyand modify the contentTypewhen you've specified data to be sent with the delete request.
    • Pros: You can call model.destroy()and optionally pass in an optionsparameter
  • Solution 2- Override the Model.sync method.
    • Pros: The override only affects individual models. Isolated changes.
    • Cons: All models that wish to delete with data need to extend from the correct 'base model'
  • Solution 3- Don't override anything and explicitly call model.sync with all of the stringifyand contentTypestuff.
    • Pros: Very isolated changes, won't affect any other models. Useful if you're integrating with a large codebase.
  • 解决方案 1:覆盖 Global Backbone.syncJSON.stringify并修改contentType指定要随删除请求发送的数据的时间。
    • 优点:您可以调用model.destroy()并选择传入options参数
  • 解决方案 2- 覆盖 Model.sync 方法。
    • 优点:覆盖仅影响单个模型。孤立的变化。
    • 缺点:所有希望删除数据的模型都需要从正确的“基本模型”扩展
  • 解决方案3-不要覆盖任何东西,显式调用model.sync所有的stringifycontentType东西。
    • 优点:非常孤立的更改,不会影响任何其他模型。如果您要与大型代码库集成,则很有用。

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

[解决方案1] - 全局覆盖Backbone.sync(这将影响所有模型)

javacript version

java脚本版本

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]);
}

Usage:

用法

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.

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

override

覆盖

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

usage

用法

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.

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

If sending data with your destroy requests is an isolated thing, then this is an adequate solution.

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

When calling model.destroy()pass in the dataand contentTypeoptions like so:

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

javascript version/usage

javascript 版本/用法

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


The "Problem" (with Backbone, not solutions):

“问题”(使用 Backbone,而不是解决方案):

Backbone.js makes the assumption (view source) that delete requests do nothave a data payload.

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));
}

In their assumed RESTful API call, the only data required is the ID which should be appended to a urlRootproperty.

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

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

The delete request would be sent like

删除请求将像

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

回答by glortho

Params need to be sent in options.data, so try:

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

coffeescript

咖啡脚本

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

javascript

javascript

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