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
Override Backbone.sync() at Model level to send extra params?
提问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.stringify
and modify thecontentType
when you've specified data to be sent with the delete request.- Pros: You can call
model.destroy()
and optionally pass in anoptions
parameter
- Pros: You can call
- 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
stringify
andcontentType
stuff.- Pros: Very isolated changes, won't affect any other models. Useful if you're integrating with a large codebase.
- 解决方案 1:覆盖 Global Backbone.sync
JSON.stringify
并修改contentType
指定要随删除请求发送的数据的时间。- 优点:您可以调用
model.destroy()
并选择传入options
参数
- 优点:您可以调用
- 解决方案 2- 覆盖 Model.sync 方法。
- 优点:覆盖仅影响单个模型。孤立的变化。
- 缺点:所有希望删除数据的模型都需要从正确的“基本模型”扩展
- 解决方案3-不要覆盖任何东西,显式调用model.sync所有的
stringify
和contentType
东西。- 优点:非常孤立的更改,不会影响任何其他模型。如果您要与大型代码库集成,则很有用。
[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 data
and contentType
options like so:
当调用model.destroy()
传入data
和contentType
选项时,如下所示:
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 urlRoot
property.
在他们假设的 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'
});
}