【问题标题】:Backbone Models - change URL query params depending on REST action骨干模型 - 根据 REST 操作更改 URL 查询参数
【发布时间】:2015-11-14 18:26:12
【问题描述】:

在 Backbone 模型中,我们有 url 和 urlRoot 属性:

           url: function(){

               return '/jobs'
            },


            urlRoot: function () {

                return '/jobs'
            },

但是我想向 url 添加参数或查询参数,具体取决于它是 GET、POST、PUT、DELETE 等的请求类型。

所以我想做这样的事情:

     url: function(type, opts){ //type and opts arguments are not available in Backbone, I just made them up for this example

          var url = '/jobs';

           switch (type) {
              case 'GET':
                break;
              case 'POST':
                break;
              case 'PUT':
                url = url + '?optimisticDelete=' + opts.optimisticDelete;
                break;
              case 'DELETE':
                url = url + '?upsert=' + opts.upsert;
                break;

               default:
                 throw new Error('no match');
                }

          return url;
    },

有什么好的方法可以完成这样的事情吗?

【问题讨论】:

    标签: javascript backbone.js


    【解决方案1】:

    默认情况下,Backbone 模型和集合委托给Backbone.sync 函数与服务器交互。这就是您可以访问示例中的 HTTP 方法的范围。您可以覆盖模型或集合上的同步功能以自定义此行为。查看documentationsource codeBackbone.syncfor jQuery.ajaxBackbone.sync 使用。

    我已经有一段时间没有接触过 Backbone 或 JavaScript,但我想它会看起来像这样(这基本上是伪代码,不要指望它像写的那样工作):

    sync: function (method, model, options) {
        // method corresponds to the HTTP verb ("type" in your example)
        switch (method) {
          // ...build the correct url like in your example...
        }
        options = options || {};
        options.url = url; // tack correct url onto options object
        return Backbone.sync.apply(this, [method, model, options]);
    }
    

    这很可能需要比这更多的摆弄,但希望它能够理解这一点。

    【讨论】:

    • 这是完全正确的。您需要覆盖同步。 trvrfrd 指出的该文档中的足够探索将解释为什么这是正确的。这个人应该得到赏金。
    【解决方案2】:

    如果您在创建网址时可以指定type,我认为您所拥有的已经足够了。

    urlExtended: function(type, opts) {
        var url = this.url();
    
        switch (type) {
        case 'GET':
            break;
        case 'POST':
            break;
        case 'PUT':
            url = url + '?optimisticDelete=' + opts.optimisticDelete;
            break;
        case 'DELETE':
            url = url + '?upsert=' + opts.upsert;
            break;
    
        default:
            throw new Error('no match');
        }
    
        return url;
    }
    

    缺点是 1. 需要 url() 时需要自己调用 urlExtend(),2. 你必须自己提供 'type' 参数。

    如果你不喜欢这样,你可以覆盖 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();
        // }
    
          if (!options.url) {
              if(model.urlExtended) {
                  // type is GET, POST...
                  // options are what you passed to fetch, save, etc.. as options
                  params.url = model.urlExtended(type, options);
              } else {
                  params.url = _.result(model, 'url') || urlError();
              }
          }
    ... rest of Backbone.sync code..
    

    您可以在加载 Backbone 后放置上述代码以覆盖同步。

    【讨论】:

      【解决方案3】:

      如果您需要控制变量,除了模型属性之外,我们还可以采取完全不同的方法并为请求添加适当的标头,这样我们就不必修改核心并投入时间进行测试。

      var MyModel = new Backbone.Model();
      
      
      if(MyModel.isNew()){  //create
        MyModel.save(MyModel.attributes, { headers: { 'create': 'true' }});
      }else{
        MyModel.save({}, { headers: { 'upsert': 'true' }});  
      }
      

      //GET & DELETE也可以类似处理

        MyModel.fetch({ headers: { 'get': 'true' }});  
      
        MyModel.delete({ headers: { 'delete': 'true' }});
      

      以上代码未经测试,但应该可以正常工作。

      参考资料:

      http://backbonejs.org/#Model-save

      http://backbonejs.org/#Model-isNew

      How can I add a custom HTTP header to ajax request with js or jQuery?

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-13
        • 2015-10-26
        相关资源
        最近更新 更多