35

我有一個Backbone.js模型,我試圖在用戶點擊模型視圖中的鏈接時銷燬。該視圖是這樣的(僞代碼,因爲它在CoffeeScript中實現,可以在問題的底部找到)。Backbone model.destroy()調用錯誤回調函數,即使它工作正常嗎?

var window.ListingSaveView = Backbone.View.extend({ 
    events: { 
    'click a.delete': 'onDestroy' 
    }, 

    onDestroy: function(event){ 
    event.preventDefault(); 
    this.model.destroy({ 
     success: function(model, response){ 
     console.log "Success"; 
     }, 
     error: function(model, response){ 
     console.log "Error"; 
     } 
    }); 
    } 
}); 

當我點擊瀏覽器中的delete鏈接,我總是得到Error登錄到控制檯,即使我的服務器記錄相關的數據庫記錄的成功銷燬,並返回200響應。當我刷新頁面(導致集合從數據庫重新渲染)時,我刪除的模型將消失。

一個有趣的是,當我在錯誤回調中登錄response時,它的狀態碼200表示成功,但它也報告statusText: "parseerror"無論如何。我的服務器日誌中沒有錯誤。

我在做什麼錯?

這是來自服務器的響應:

Object 
    abort: function (statusText) { 
    always: function() { 
    complete: function() { 
    done: function() { 
    error: function() { 
    fail: function() { 
    getAllResponseHeaders: function() { 
    getResponseHeader: function (key) { 
    isRejected: function() { 
    isResolved: function() { 
    overrideMimeType: function (type) { 
    pipe: function (fnDone, fnFail) { 
    promise: function (obj) { 
    readyState: 4 
    responseText: " " 
    setRequestHeader: function (name, value) { 
    status: 200 
    statusCode: function (map) { 
    statusText: "parsererror" 
    success: function() { 
    then: function (doneCallbacks, failCallbacks) { 
    __proto__: Object 

這裏是服務器的行動,摧毀與(Ruby on Rails的)

# DELETE /team/listing_saves/1.json 
    def destroy 
    @save = current_user.team.listing_saves.find(params[:id]) 
    @save.destroy 
    respond_to do |format| 
     format.json { head :ok } 
    end 
    end 

相互作用,這裏是實際的CoffeeScript實現骨幹查看喜歡的人:

class MoveOutOrg.Views.ListingSaveView extends Backbone.View 
    tagName: 'li' 
    className: 'listing_save' 
    template: JST['backbone/templates/listing_save'] 
    events: 
    'click a.delete_saved': 'onDestroy' 

    initialize: -> 
    @model.bind 'change', this.render 
    render: => 
    renderedContent = @template(@model.toJSON()) 
    $(@el).html(renderedContent) 
    this 
    onDestroy: (event) -> 
    event.preventDefault() # stop the hash being added to the URL 
    console.log "Listing Destroyed" 
    @model.destroy 
     success: (model, response)-> 
     console.log "Success" 
     console.log model 
     console.log response 

     error: (model, response) -> 
     console.log "Error" 
     console.log model # this is the ListingSave model 
     console.log response 
+0

你可以粘貼任何服務器發送回來的東西(使用螢火蟲或其他東西來打開響應),如果有的話? – Stephen

+0

編輯我的問題,包括回覆 –

+1

哦。那麼,直言不諱,這不是一個有效的迴應。這很可能是在聽一個JSON響應..不管怎樣,你都沒有給它一個。我不記得我們在Rails中使用什麼,但它就像to_json,而不僅僅是'json'(我不是一個紅寶石專家,或者甚至是新手......所以我無法幫助過去) – Stephen

回答

51

@David Tuite comm ent:

「好的,我想通了。看起來Backbone希望JSON響應是被銷燬的記錄的JSON序列化。但是,Rails控制器生成器僅返回頭部:默認情況下爲ok。我改變了我的JSON響應是渲染JSON:@listing_save其中@listing_save是我破壞了記錄,並註冊成功「

僅供參考 - 當你做一個毀滅,你不需要。你可以返回一個空的json散列,它會工作得很好,你只需要返回模型的json就可以保存/更新。

+3

好的你可以擁有積分。即使我做了一半的工作;) –

+0

骨幹對鐵路非常敏感json結果 –

+2

雖然你不必返回模型,但有時候這樣做很不錯。一種情況是,當你不使用destroy的{wait:true}參數的時候,這實際上是一個很好的方法 - 這樣,如果操作失敗,你可以輕鬆地重新添加模型到集合中,以保持集合更新。 –

0

你確定嗎?您的網址?您在Backbone.Model網址的末尾添加.json?因爲您在服務器端檢查了這個(respond_to do | format | ... end),您可能不會發送正確的head :ok響應

這種destroy軌方法嘗試測試,如果是這樣的問題:

def destroy 
    @save = current_user.team.listing_saves.find(params[:id]) 
    @save.destroy 
    head :ok 
end 
7

你的反應必須有狀態碼204,你將不會返回任何內容。由於主幹使用REST接口,因此根據任務的不同,應該返回不同的http狀態代碼。

16

我有這個相同的問題。在我的服務器上的刪除方法(Java),我沒有返回任何東西。只是狀態200/OK(或204 /無內容)。因此,「parsererror」問題是由jquery試圖將空響應轉換爲JSON導致的,失敗(因爲「json」是默認數據類型)。

我的解決辦法是使用「文本」數據類型來代替,這可以在選項中設置:

model.destroy({ dataType: "text", success: function(model, response) { 
    console.log("success"); 
}}); 
+0

好的。謝謝。 – chikamichi

+2

我也使用過'model.destroy({contentType:false,processData:false})'。 – carpeliam

0

的LAMP服務器上使用超薄框架,你可以添加一個Response StatusDELETE路線(或自定義不返回任何路由)

$app->response()->status(204);//204 No Content

這也設置了內容類型與文本/ HTML,以允許爲空體

相關問題