Javascript 向主干模型添加功能?
我正在试图找出实现自定义更新的“正确”方法 Backbone.js模型中的函数。我尝试做的一个例子是:Javascript 向主干模型添加功能?,javascript,ajax,html,rest,backbone.js,Javascript,Ajax,Html,Rest,Backbone.js,我正在试图找出实现自定义更新的“正确”方法 Backbone.js模型中的函数。我尝试做的一个例子是: var Cat = Backbone.Model.extend({ defaults: { name : 'Mr. Bigglesworth', location : 'Living Room', action : 'sleeping' }, sleep: function () { // POST /cats/{{ cat_id }
var Cat = Backbone.Model.extend({
defaults: {
name : 'Mr. Bigglesworth',
location : 'Living Room',
action : 'sleeping'
},
sleep: function () {
// POST /cats/{{ cat_id }}/action
// { action: "sleep" }
},
meow: function () {
// POST /cats/{{ cat_id }}/action
// { action: "meow" }
}
})
据我所知,Backbone.Collection.save()方法只执行
以下:
POST /cats/{{ cat_id }}
{ name: 'Mr. Bigglesworth', location: 'Living Room', action: '{{ value }} '}
但我使用的API不允许我以这种方式更改操作
,只能通过以下方式:
POST /cats/{{ cat_id }}/action
{ action: "{{ value }}" }
希望这有意义
任何帮助都将不胜感激。您可以在调用save时将URL作为参数传递。也许你可以这样做:
var Cat = Backbone.Model.extend({
urlRoot: '/cats/',
defaults: {
name : 'Mr. Bigglesworth',
location : 'Living Room',
action : 'sleeping'
},
sleep: function () {
var custom_url = this.urlRoot + this.id + "/action";
this.save({}, { url: custom_url});
// POST /cats/{{ cat_id }}/action
// { action: "sleep" }
},
});
请参见此处:
如果您总是希望在更新时使用自定义URL,还可以实现同步方法以使用另一个URL。请参见此处的示例:。您可以采取不同的方法来解决此问题,但在我看来,最干净的方法是覆盖Backbone.sync,以便在连接到的服务器后端具有通用性的情况下,按照您希望的方式进行操作
例如,如果您希望每个模型/集合都与特定的后端实现交互,那么这种方法非常有意义
通过这种方式,您可以将集合(或模型)的其余代码保留为主干默认代码,但它将按照您希望的方式工作
例如:
// Store the default Backbone.sync so it can be referenced later
Backbone.vanillaSync = Backbone.sync;
// Most of this is just copy-pasted from the original 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();
}
// START ADD YOUR LOGIC HERE TO ADD THE /action
// Add the action to the url
params.url = params.url + '/' + options.action;
// Remove the action from the options array so it isn't passed on
delete options.action;
// END ADD YOUR LOGIC HERE TO ADD THE /action
// Ensure that we have the appropriate request data.
if (options.data == null && model && (method === 'create' || method === 'update' || method === 'patch')) {
params.contentType = 'application/json';
params.data = JSON.stringify(options.attrs || model.toJSON(options));
}
// For older servers, emulate JSON by encoding the request into an HTML-form.
if (options.emulateJSON) {
params.contentType = 'application/x-www-form-urlencoded';
params.data = params.data ? {model: params.data} : {};
}
// For older servers, emulate HTTP by mimicking the HTTP method with `_method`
// And an `X-HTTP-Method-Override` header.
if (options.emulateHTTP && (type === 'PUT' || type === 'DELETE' || type === 'PATCH')) {
params.type = 'POST';
if (options.emulateJSON) params.data._method = type;
var beforeSend = options.beforeSend;
options.beforeSend = function(xhr) {
xhr.setRequestHeader('X-HTTP-Method-Override', type);
if (beforeSend) return beforeSend.apply(this, arguments);
};
}
// Don't process data on a non-GET request.
if (params.type !== 'GET' && !options.emulateJSON) {
params.processData = false;
}
// If we're sending a `PATCH` request, and we're in an old Internet Explorer
// that still has ActiveX enabled by default, override jQuery to use that
// for XHR instead. Remove this line when jQuery supports `PATCH` on IE8.
if (params.type === 'PATCH' && window.ActiveXObject &&
!(window.external && window.external.msActiveXFilteringEnabled)) {
params.xhr = function() {
return new ActiveXObject("Microsoft.XMLHTTP");
};
}
// Make the request, allowing the user to override any Ajax options.
var xhr = options.xhr = Backbone.ajax(_.extend(params, options));
model.trigger('request', model, xhr, options);
return xhr;
};
在上面的示例中,我假设您已经通过选项数组发送了操作,如果您确实想要静态单词/操作,您可以将该块替换为:
// Add the action to the url
params.url = params.url + '/action';
这将为您提供最干净的实现,同时保持代码的其余部分干净 我很喜欢你这样做的方式,但我需要更多的基于具体情况的东西(每个集合/模型的行为会有很大的不同)-根据你的例子,这样做有效吗?