2015-08-20 14 views
7

內部骨幹模型,我們有URL和urlRoot屬性:骨幹模式 - 改變URL查詢參數取決於REST行動

  url: function(){ 

       return '/jobs' 
      }, 


      urlRoot: function() { 

       return '/jobs' 
      }, 

但是我想params中,查詢參數添加到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; 
    }, 

有沒有做到像這樣的好辦法?

回答

6

默認情況下,骨幹模型和集合委託給Backbone.sync功能與服務器進行交互。這就是您可以像訪問示例一樣訪問HTTP方法的範圍。您可以覆蓋模型或集合上的同步功能以自定義此行爲。退房documentationsource codeBackbone.syncfor jQuery.ajax,這Backbone.sync使用。

我沒碰過骨幹或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]); 
} 

它很可能會採取比這更多的擺弄,但希望它橫跨得到點。如果你需要控制變量,那麼我們也可以採取完全不同的方法,並添加適當的報頭的請求,這樣我們就不必修改核心和測試投入時間

+1

這是完全正確的。您需要覆蓋同步。在文檔trvrfrd指出的足夠的探索將解釋爲什麼這是正確的。這個人應該得到賞金。 –

2
從模型

除了屬性。

var MyModel = new Backbone.Model(); 


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

//獲取& 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?

3

我覺得你有什麼是不夠好,如果當你創建的網址,您可以指定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需要調用urlExtend()自己需要的網址()時,2。你必須提供「類型」參數yourslf。

如果你不喜歡,你可以覆蓋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.. 

加載骨幹覆蓋同步後,您可以將上面的代碼。