8

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

例如。api.site.com将是 REST 服务,但出于测试目的,localhost:1000我可能需要能够轻松更改服务的根 url,而不是在应用程序中存在的许多模型中到处都有它们。

4

7 回答 7

13

在将 Backbone 与 AMD (require.js) 一起使用时,我一直在尝试最优雅的方式来做到这一点。这就是我想出的,并且最喜欢[到目前为止]。

首先,将数据引导到其中,如此所述。

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/models/User.js

define(['models/Base'],
  function(BaseModel){

    return BaseModel.extend({
      urlRoot: function(){
        return this.getApiUrl() + '/user';
      }
      // ... more cool stuff here
    });

  }
);

这与我之前提出的关于 Backbone 和 Require.JS 的问题有密切关系。

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

于 2013-03-20T16:05:52.827 回答
8

我的理解是:

您有几个模型:model1 和 model2

根 URL 可以是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',
...
});

但是请注意这一点,您可能会在提交时忘记从一个 url 切换到另一个。如果它们适用,更好的是处理相对路径。

于 2012-11-14T11:19:37.413 回答
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到所有 URL,以防止 JSON 通过浏览器缓存闪烁。

于 2015-05-22T11:39:37.543 回答
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);
};
于 2016-01-26T21:18:16.253 回答
1

不确定urlRoot手动为每个模型设置的确切含义。大概你会

var MyModel = Backbone.Model.extend({

  urlRoot: '/mymodel',
  ...

});

正确的?那么每个模型实例自然都有相同urlRoot的。说的任何其他模型实例MyOtherModel都会有一些不同urlRoot

如果由于某种原因您需要使用相同的urlRoot,我猜这是因为模型共享属性。这应该暗示继承或扩展,所以你可以这样做:

var BaseModel = Backbone.Model.extend({
  urlRoot: '/mymodel'
});

var MyModel = BaseModel.extend({
  ...
});
于 2012-04-28T21:42:28.843 回答
0

只需从'/'开始您的网址。因此,您将不依赖于本地主机或真实域。

于 2014-05-05T21:08:05.187 回答
0

这是一个很老的帖子,但我认为我的版本可能对某人有用。我将骨干网与 require.js 一起使用,并且我的服务器端和客户端完全分开。当我声明 requirejs 脚本时,我会同时告知客户端应用程序的 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({});

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

于 2016-12-08T16:17:38.583 回答