2011-07-13 63 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本身处理