2011-05-21 76 views
12

我正在使用backbone.js與REST API進行交互,當發佈到它以創建新資源時,將響應狀態爲201,一個'Location'頭指向資源的URI,但是一個空的主體。在Backbone.js中處理REST API的'創建'響應的最佳方式

當我創建一個新模型的時候,它的成功,但是模型的本地表示只包含我明確設置的屬性,而不是任何將在服務器上設置的屬性(created_date等)

從我所瞭解的情況來看,Backbone會更新它在模型中的數據表示,如果有的話。但是,由於沒有,它沒有。

因此,顯然,我需要使用位置標題中的位置來更新模型,但是最好的方法是什麼。

我目前的想法是,我將不得不從頭中解析url,拆分id,設置模型的id,然後告訴模型去fetch()。

這似乎很混亂。有沒有更乾淨的方法來做到這一點?

我對API有一些影響。嘗試讓API作者返回新模型作爲響應的主體(同時保留201和位置標題)是最佳解決方案嗎?

謝謝!

+1

這可能有一些幫助:https://github.com/PaulUithol/backbone-tastypie/blob/master/backbone_tastypie/static/js/backbone-tastypie.js#L15 – dlamotte 2012-01-04 20:22:19

回答

7

聽起來像你將不得不做一點點定製。 也許會覆蓋繼承自 Backbone.Model的模型類的解析方法和url方法。

繼承的功能是:

url : function() { 
    var base = getUrl(this.collection); 
    if (this.isNew()) return base; 
    return base + (base.charAt(base.length - 1) == '/' ? '' : '/') + this.id; 
}, 
parse : function(resp) { 
    return resp; 
}, 

,你可以嘗試這樣的:

parse: function(resp, xhr) { 
    this._url = xhr.getResponseHeader('location') 
    return resp 
} 
url: function() { 
    return this._url 
} 
+0

我喜歡處理這個想法Parse方法。 – 2011-05-26 13:41:46

5

是的,backbone.js真的希望保存的結果(是PUT或POST)成爲可用於更新模型的可分析體。如果如您所說,您對API有影響力,您應該看看您是否可以安排內容主體包含資源屬性。

正如您所指出的那樣,進行第二次線上呼叫以完全實現模型是沒有意義的。

這可能是一個200的狀態代碼更合適。純粹主義者可能認爲201狀態碼意味着只有一個位置被返回,而不是實體。顯然,在這種情況下這沒有意義。

2

隨着骨幹0.9.9,我沒能接受的答案工作。 parse功能的簽名似乎已在舊版本中發生了變化,並且xhr對象在功能簽名中不再可用。

這是我做的一個例子,它使它與Backbone v0.9.9和jQuery 1.8一起工作。3(使用Deferred Object/Promise),依靠由Backbone.Model.save()返回jqXHR object

window.CompanyView = Backbone.View.extend({ 
// ... omitted other functions... 

    // Invoked on a form submit 
    createCompany: function(event) { 
     event.preventDefault(); 
     // Store a reference to the model for use in the promise 
     var model = this.model; 
     // Backbone.Model.save returns a jqXHR object 
     var xhr = model.save(); 
     xhr.done(function(resp, status, xhr) { 
      if (!model.get("id") && status == "success" && xhr.status == 201) { 
       var location = xhr.getResponseHeader("location"); 
       if (location) { 
        // The REST API sends back a Location header of format http://foo/rest/companys/id 
        // Split and obtain the last fragment 
        var fragments = location.split("/"); 
        var id = fragments[fragments.length - 1]; 
        // Set the id attribute of the Backbone model. This also updates the id property 
        model.set("id", id); 
        app.navigate('companys/' + model.id, {trigger: true}); 
       } 
      } 
     }); 
    } 
}); 

我沒有使用success回調,可以在提供給Backbone.Model.save功能options哈希指定,因爲該回調之前調用接收到XHR響應。也就是說,存儲對jqXHR對象的引用並在success回調中使用它是沒有意義的,因爲在調用回調時jqXHR將不包含任何響應頭(尚)。

另一個解決此問題的方法是編寫自定義的Backbone.sync實現,但我不喜歡這種方法。

相關問題