Backbone 模型 - 根据 REST 操作更改 URL 查询参数
Backbone Models - change URL query params depending on REST action
在 Backbone 模型中,我们有 url 和 url 根属性:
url: function(){
return '/jobs'
},
urlRoot: function () {
return '/jobs'
},
但是我想向 url 添加参数或查询参数,具体取决于它是 GET、POST、PUT、DELETE 等请求的类型
所以我想做这样的事情:
url: function(type, opts){ //type and opts arguments are not available in Backbone, I just made them up for this example
var url = '/jobs';
switch (type) {
case 'GET':
break;
case 'POST':
break;
case 'PUT':
url = url + '?optimisticDelete=' + opts.optimisticDelete;
break;
case 'DELETE':
url = url + '?upsert=' + opts.upsert;
break;
default:
throw new Error('no match');
}
return url;
},
有什么好的方法可以完成这样的事情吗?
默认情况下,Backbone 模型和集合委托给 Backbone.sync
函数与服务器交互。这就是您可以访问示例中的 HTTP 方法的范围。您可以覆盖模型或集合上的同步功能以自定义此行为。查看 documentation and source code for Backbone.sync
and for jQuery.ajax,Backbone.sync
使用。
我有一段时间没有接触 Backbone 或 JavaScript,但我想它看起来像这样(这基本上是伪代码,不要指望它能工作如所写):
sync: function (method, model, options) {
// method corresponds to the HTTP verb ("type" in your example)
switch (method) {
// ...build the correct url like in your example...
}
options = options || {};
options.url = url; // tack correct url onto options object
return Backbone.sync.apply(this, [method, model, options]);
}
它很可能需要比这更多的摆弄,但希望它能说明问题。
除了模型属性之外,如果您需要控制变量,那么我们也可以采用完全不同的方法并在请求中添加适当的 headers,这样我们就不必修改核心并投入时间测试。
var MyModel = new Backbone.Model();
if(MyModel.isNew()){ //create
MyModel.save(MyModel.attributes, { headers: { 'create': 'true' }});
}else{
MyModel.save({}, { headers: { 'upsert': 'true' }});
}
//GET&DELETE可以类似处理
MyModel.fetch({ headers: { 'get': 'true' }});
MyModel.delete({ headers: { 'delete': 'true' }});
以上代码未经测试,但应该可以正常工作。
参考文献:
http://backbonejs.org/#Model-save
http://backbonejs.org/#Model-isNew
How can I add a custom HTTP header to ajax request with js or jQuery?
我认为如果您在创建 url 时指定 type
就足够了。
urlExtended: function(type, opts) {
var url = this.url();
switch (type) {
case 'GET':
break;
case 'POST':
break;
case 'PUT':
url = url + '?optimisticDelete=' + opts.optimisticDelete;
break;
case 'DELETE':
url = url + '?upsert=' + opts.upsert;
break;
default:
throw new Error('no match');
}
return url;
}
缺点是 1. 需要 url() 时需要自己调用 urlExtend(),2. 您必须自己提供 'type' 参数。
如果您不喜欢这样,您可以覆盖 Backbone.sync
Backbone.sync = function(method, model, options) {
var type = methodMap[method];
// Default options, unless specified.
_.defaults(options || (options = {}), {
emulateHTTP: Backbone.emulateHTTP,
emulateJSON: Backbone.emulateJSON
});
// Default JSON-request options.
var params = {type: type, dataType: 'json'};
// Ensure that we have a URL.
// if (!options.url) {
// params.url = _.result(model, 'url') || urlError();
// }
if (!options.url) {
if(model.urlExtended) {
// type is GET, POST...
// options are what you passed to fetch, save, etc.. as options
params.url = model.urlExtended(type, options);
} else {
params.url = _.result(model, 'url') || urlError();
}
}
... rest of Backbone.sync code..
您可以在加载后放置上述代码 Backbone 以覆盖同步。
在 Backbone 模型中,我们有 url 和 url 根属性:
url: function(){
return '/jobs'
},
urlRoot: function () {
return '/jobs'
},
但是我想向 url 添加参数或查询参数,具体取决于它是 GET、POST、PUT、DELETE 等请求的类型
所以我想做这样的事情:
url: function(type, opts){ //type and opts arguments are not available in Backbone, I just made them up for this example
var url = '/jobs';
switch (type) {
case 'GET':
break;
case 'POST':
break;
case 'PUT':
url = url + '?optimisticDelete=' + opts.optimisticDelete;
break;
case 'DELETE':
url = url + '?upsert=' + opts.upsert;
break;
default:
throw new Error('no match');
}
return url;
},
有什么好的方法可以完成这样的事情吗?
默认情况下,Backbone 模型和集合委托给 Backbone.sync
函数与服务器交互。这就是您可以访问示例中的 HTTP 方法的范围。您可以覆盖模型或集合上的同步功能以自定义此行为。查看 documentation and source code for Backbone.sync
and for jQuery.ajax,Backbone.sync
使用。
我有一段时间没有接触 Backbone 或 JavaScript,但我想它看起来像这样(这基本上是伪代码,不要指望它能工作如所写):
sync: function (method, model, options) {
// method corresponds to the HTTP verb ("type" in your example)
switch (method) {
// ...build the correct url like in your example...
}
options = options || {};
options.url = url; // tack correct url onto options object
return Backbone.sync.apply(this, [method, model, options]);
}
它很可能需要比这更多的摆弄,但希望它能说明问题。
除了模型属性之外,如果您需要控制变量,那么我们也可以采用完全不同的方法并在请求中添加适当的 headers,这样我们就不必修改核心并投入时间测试。
var MyModel = new Backbone.Model();
if(MyModel.isNew()){ //create
MyModel.save(MyModel.attributes, { headers: { 'create': 'true' }});
}else{
MyModel.save({}, { headers: { 'upsert': 'true' }});
}
//GET&DELETE可以类似处理
MyModel.fetch({ headers: { 'get': 'true' }});
MyModel.delete({ headers: { 'delete': 'true' }});
以上代码未经测试,但应该可以正常工作。
参考文献:
http://backbonejs.org/#Model-save
http://backbonejs.org/#Model-isNew
How can I add a custom HTTP header to ajax request with js or jQuery?
我认为如果您在创建 url 时指定 type
就足够了。
urlExtended: function(type, opts) {
var url = this.url();
switch (type) {
case 'GET':
break;
case 'POST':
break;
case 'PUT':
url = url + '?optimisticDelete=' + opts.optimisticDelete;
break;
case 'DELETE':
url = url + '?upsert=' + opts.upsert;
break;
default:
throw new Error('no match');
}
return url;
}
缺点是 1. 需要 url() 时需要自己调用 urlExtend(),2. 您必须自己提供 'type' 参数。
如果您不喜欢这样,您可以覆盖 Backbone.sync
Backbone.sync = function(method, model, options) {
var type = methodMap[method];
// Default options, unless specified.
_.defaults(options || (options = {}), {
emulateHTTP: Backbone.emulateHTTP,
emulateJSON: Backbone.emulateJSON
});
// Default JSON-request options.
var params = {type: type, dataType: 'json'};
// Ensure that we have a URL.
// if (!options.url) {
// params.url = _.result(model, 'url') || urlError();
// }
if (!options.url) {
if(model.urlExtended) {
// type is GET, POST...
// options are what you passed to fetch, save, etc.. as options
params.url = model.urlExtended(type, options);
} else {
params.url = _.result(model, 'url') || urlError();
}
}
... rest of Backbone.sync code..
您可以在加载后放置上述代码 Backbone 以覆盖同步。