在backbone.js中,您必须手动设置每个模型的rooturl。有没有办法我们可以在一个位置设置一次,所有模型都会使用它?
例如。 api.site.com
将是REST服务,但出于测试目的,它可能位于localhost:1000
我需要能够轻松地更改服务的根网址,而不是将它们全部放在许多地方应用程序中存在的模型。
答案 0 :(得分:13)
在使用Backbone和AMD(require.js)时,我一直在玩最优雅的方法。这就是我想出来的,并且最好[到目前为止]。
首先,按照here所描述的那样引导数据。
index.htm(应用程序入口点)
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<script>
var require = {
config: {
// key name is module, value is data to give module
'models/Base': {
apiUrl: '/some/path/to/api',
}
}
}
</script>
<script data-main="js/main" src="vendor/require/require-jquery.js"></script>
</head>
<body></body>
</html>
接下来,为Backbone模型定义一个基类,如下所示:
js / models / Base.js(注意此模块名称与上面配置中的模块名称相匹配)
define(['module', 'backbone'],
function(module, Backbone){
return Backbone.Model.extend({
getApiUrl: function(){
return module.config().apiUrl;
}
});
}
);
最后,从该基础扩展所有Backbone模型,如下所示:
<强> JS /模型/ user.js的强>
define(['models/Base'],
function(BaseModel){
return BaseModel.extend({
urlRoot: function(){
return this.getApiUrl() + '/user';
}
// ... more cool stuff here
});
}
);
这与关于Backbone和Require.JS的earlier question I had切线相关。
答案 1 :(得分:8)
我的理解是:
您有几种型号:model1和model2
根网址可以是http://api.site.com
或http://localhost:8080
,具体取决于您是在本地还是在外部工作。有一天它可能是http://api.anothersite.com
我会做这样的事情:
// Global var before any other JS code, you comment line depending on which one applies
var ROOT = 'http://api.site.com'
// var ROOT = 'http://localhost:8080'
var Model1 = Backbone.Model.extend({
urlRoot: ROOT+'/model1',
...
});
var Model2 = Backbone.Model.extend({
urlRoot: ROOT+'/model2',
...
});
但要小心,你可能会在提交时忘记从一个网址切换到另一个网址。如果他们适用,最好处理相对路径。
答案 2 :(得分:2)
在我看来,实现这一目标的最佳方法是覆盖Backbone.sync
方法,并在那里添加根URL。这是因为了解API域并不是模型的责任。
// Cache Backbone.sync for later use
var sync = Backbone.sync;
Backbone.sync = function(method, model, options){
options.beforeSend = function(){
this.url = API_ROOT_URL + this.url;
};
return sync.call(this, method, model, options);
};
然后您可以像平常一样创建模型:
var Resource = Backbone.Model.extend({
urlRoot: '/resources',
});
我使用相同的方法将.json
扩展名附加到所有网址,以防止JSON通过浏览器缓存闪烁。
答案 3 :(得分:2)
改编自https://coderwall.com/p/8ldaqw/add-a-root-url-to-all-backbone-api-request
var backboneSync = Backbone.sync;
Backbone.sync = function (method, model, options) {
/*
* Change the `url` property of options to begin
* with the URL from settings
* This works because the options object gets sent as
* the jQuery ajax options, which includes the `url` property
*/
options = _.extend(options, {
url: API_ROOT + _.result(model, 'url')
});
/*
* Call the stored original Backbone.sync
* method with the new url property
*/
backboneSync(method, model, options);
};
答案 4 :(得分:1)
不确定您的意思是手动为每个型号设置urlRoot
。
大概是你做的
var MyModel = Backbone.Model.extend({
urlRoot: '/mymodel',
...
});
正确?然后每个模型实例自然具有相同的urlRoot
。说MyOtherModel
的任何其他模型实例都会有一些不同的urlRoot
。
如果由于某种原因你需要使用相同的urlRoot
,我猜它会是因为模型共享属性。这应该暗示继承或扩展,所以你可以这样做:
var BaseModel = Backbone.Model.extend({
urlRoot: '/mymodel'
});
var MyModel = BaseModel.extend({
...
});
答案 5 :(得分:0)
只需从'/'开始您的网址。 因此,您将不依赖于localhost或real domain。
答案 6 :(得分:0)
这是一个很老的帖子,但我认为我的版本对某些人有用。我使用backbone和require.js,我的服务器端和客户端完全分开。当我声明requirejs脚本时,我同时知道客户端应用程序API API的位置:
<script
data-main="js/main"
data-api-url="https://api/v1/"
src="js/require.js">
</script>
然后我进入我的骨干模块:
var $scriptEl = $('script[data-main]'),
base = $scriptEl.attr('data-api-url');
var BaseModel = Backbone.Model.extend({
urlRoot: base
});
var model = BaseModel.extend({});
这是我能找到的最优雅的方式..