2011-07-13 91 views
7

我在視圖中刪除模型中的集合中的項目時遇到了一些麻煩。基本上,該模型/收集結構如下:backbone.js集合沒有正確刪除視圖中的項目

enter image description here

基本上當我試圖從分項集合中的子項中刪除項目查看它實際上是從集合中刪除正確的項目。但是,當我堅持主要模型時,該項目似乎仍然在收藏中。
這是怎麼我的觀點是結構化:

enter image description here

的主視圖插入由主模型所需的DOM節點,並將其主力機型創造了該項目模型等的觀點,都是一個新的觀點得到主力車型爲模型的選擇,像這樣:

new App.Views.MainModelView({ 
    model : this.model, 
    el : $('#nodeID') 
}) 

唯一的區別是在創建子項的模型圖,其中,由於重新視圖和模板的可用性,我還通過在主模型,但是我也傳遞了項目集合中的項目正在修改。它看起來像這樣:

new App.Views.ItemView({ 
    model : this.model, 
    item : this.selectedItem, 
    el : $('#nodeID') 
}); 

在該分項的觀點init方法我做到以下幾點:

this.item = (this.options.item) ? this.options.item : this.model; 

要從子項集合我做刪除的子項

removeSubItem : function(e) { 
    // get the id of the sub-item to be removed 
    var id = $(e.target).closest('tr').attr('data-id'); 
    if (!id) throw "Could not retrieve data id"; 
    // retrieve the sub-item from the collection 
    var subItem = this.item.subItems.get(id); 
    // remove the sub-item from the collection 
    this.item.subItems.remove(subItem); 
}, 

正如我前面所說,當我刪除子項目並檢查由視圖修改的集合時,我可以看到該子項目已從集合中刪除,但是,然後我堅持刪除子模塊,項目重新出現。這使我相信,可以克隆子項目集合的某處,這可以解釋該子項目突然再現的情況。

我知道這是一個相當具體的問題,我不確定是否有可能找到我在這裏提供的問題的原因,如果您需要更多信息,請讓我知道。

感謝您的幫助,

文森特

==========編輯============

回答一些下面的問題讓我概括了我遇到此問題的範圍:

如果我在子項目視圖中記錄this.item.subItems集合,在removeSubItem被調用後,我可以看到SubItem的實例模型已成功刪除。 在我調用主模型上的save方法之前,我將控制檯記錄到toJSON函數的返回值。在這一點上,我遇到了以前刪除的實例在集合中「返回」的問題。我一直在使用Wireshark和Google chrome的開發人員控制檯監視客戶端和服務器之間的流量,並且沒有呼叫服務器刷新任何模型。

的的toJSON方法的子項集合看起來是這樣的:

toJSON : function() { 
    App.log(["SubItem::collection::toJSON", this], "info"); 
    var json = {}; 
    // make sure the key for each SubItem is the primary key 
    this.each(function(subItem) { 
    json[subItem.get('id')] = subItem.toJSON(); 
    }); 

    return json; 
} 
+0

請解釋或告訴我們你的意思是「堅持」,以及你如何做以及如何重新加載它。 – Julien

+0

當我談論堅持時,我的意思是將模型保存在服務器上,從而在主模型上調用save方法。保存是通過一系列本地或重寫的JSON方法完成的。請參閱編輯以獲取更多信息。 – luxerama

回答

2
嵌套集合

Backbone.js的支持/模型是更具體的子視圖處理上本身click事件非存在,並且它們不提供儲蓄支持(參見http://documentcloud.github.com/backbone/#FAQ-nested)。您必須在具有子集合的任何模型上重寫爲JSON。我已經遇到了這個場景一百萬次。如果你有類似的信息(在CoffeeScript中):

class MainModel extends Backbone.Model 

    itemCollection: -> 
     @_itemCollection ?= new ItemCollection(@get('itemCollection')) 


class ItemCollection extends Backbone.Collection 

    model: ItemModel 


class ItemModel extends Backbone.Model 

    subCollection: -> 
     @_subCollection ?= new SubCollection(@get('subCollection')) 


class SubCollection extends Backbone.Collection 

    model: SubModel 


class SubModel extends Backbone.Model 


mainModel = new MainModel(json) 

然後爲了mainModel.save()工作,你需要覆蓋的toJSON上MainModel和ItemModel,如:

class MainModel extends Backbone.Model 

    itemCollection: -> 
     @_itemCollection ?= new ItemCollection(@get('itemCollection')) 

    toJSON: -> 
     return _.extend(@attributes, {itemCollection: @itemCollection().toJSON()}) 


class ItemModel extends Backbone.Model 

    subCollection: -> 
     @_subCollection ?= new SubCollection(@get('subCollection')) 

    toJSON: -> 
     return _.extend(@attributes, {subCollection: @subCollection().toJSON()}) 

我寫的在coffeescript中的例子,因爲它比javascript更簡潔。如果您需要幫助瞭解它,請隨時詢問。

希望這會有所幫助!

---注意---

從技術上講,在CoffeeScript中,該方法的toJSON可以簡單地是:

toJSON: -> 
    _.extend @attributes, itemCollection: @itemCollection().toJSON() 

但我寫的我也更加理解非coffeescripters方式。

1

不看你的整個代碼庫,我想你可能也有結構稍有不妥。正常情況下,如果將el元素直接傳遞到視圖中,我幾乎不會將它傳遞給el。該視圖負責生成它自己的el。渲染完成後,我將新的view.el插入到DOM中。如下所示

var subView = new FooView({ model: fooModel }); 

mainView.$(".list").append(subView.el); 

在上述情況下,每個子視圖都有一個主幹對象。如果你需要刪除子視圖,你不需要做選擇器查詢來找到它,你只需要調用 對象的remove方法,它知道如何從dom中刪除它自己。

或者它 然後可以通過摧毀它的相關模型,然後調用remove本身處理