在Backbone.js应用程序中设置全局REST根URL

时间:2012-04-28 16:51:30

标签: backbone.js

在backbone.js中,您必须手动设置每个模型的rooturl。有没有办法我们可以在一个位置设置一次,所有模型都会使用它?

例如。 api.site.com将是REST服务,但出于测试目的,它可能位于localhost:1000我需要能够轻松地更改服务的根网址,而不是将它们全部放在许多地方应用程序中存在的模型。

7 个答案:

答案 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切线相关。

相关阅读:http://requirejs.org/docs/api.html#config-moduleconfig

答案 1 :(得分:8)

我的理解是:

您有几种型号:model1和model2

根网址可以是http://api.site.comhttp://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({});

这是我能找到的最优雅的方式..