【问题标题】:Setting a global REST root url in a Backbone.js application在 Backbone.js 应用程序中设置全局 REST 根 URL
【发布时间】:2012-04-28 16:51:30
【问题描述】:

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

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

【问题讨论】:

    标签: backbone.js


    【解决方案1】:

    在将 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/models/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

    【讨论】:

      【解决方案2】:

      我的理解是:

      你有几个模型:model1 和 model2

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

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

      【讨论】:

        【解决方案3】:

        在我看来,实现这一点的最佳方法是覆盖 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 通过浏览器缓存闪烁。

        【讨论】:

        • 我认为这行不通。 beforeSend() 在请求已经被原始 url 打开后调用。
        • 正是beforeSend的用法; beforeSend 类型:Function( jqXHR jqXHR, PlainObject settings ) 一个预请求回调函数,可用于在发送之前修改 jqXHR(在 jQuery 1.4.x 中为 XMLHTTPRequest)对象。使用它来设置自定义标题等。 jqXHR 和设置对象作为参数传递。这是一个 Ajax 事件。在 beforeSend 函数中返回 false 将取消请求。从 jQuery 1.5 开始,无论请求类型如何,都将调用 beforeSend 选项。
        • 在请求发送之前但在它初始化之后(使用现有的url)。我的回答正确。
        • 我正在使用它,我认为它最初似乎可以工作,但后来我遇到了问题。我正在使用 Backbone.NativeAjax 和 node-xmlhttprequest 在服务器上使用骨干模型,并且 node-xmlhttprequest 从初始选项中解析了 url 组件,并且在调用 beforeSend() 后没有更新解析的组件。我建议我的答案,因为它不依赖于 ajax 调用的实现细节。
        • 所以问题不在于我的解决方案。仅与非标准 Backbone 设置结合使用。无论如何,当人们不使用 jQuery 作为后端时,您的答案是一个不错的选择。您可能希望将该例外添加到您的答案中。
        【解决方案4】:

        改编自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);
        };
        

        【讨论】:

          【解决方案5】:

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

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

          对吗?然后每个模型实例自然有相同的urlRoot。任何其他模型实例比如MyOtherModel 都会有一些不同的urlRoot。

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

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

          【讨论】:

            【解决方案6】:

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

            【讨论】:

              【解决方案7】:

              这是一个很老的帖子,但我认为我的版本可能对某人有用。我将骨干网与 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({});
              

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

              【讨论】:

                猜你喜欢
                • 2011-10-14
                • 1970-01-01
                • 2010-09-05
                • 2013-03-14
                • 2011-11-19
                • 1970-01-01
                • 2012-03-13
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多