backbone.js集合没有正确删除视图中的项目

在视图中从模型中的集合删除项目时遇到问题。 基本上模型/收集结构如下:

基本上,当我尝试从子项目视图中的子项目集合中删除项目时,它实际上会从集合中删除正确的项目。 但是,当我坚持主要模型时,该项目似乎仍然在收藏中。
这是我的观点结构:

在这里输入图像描述

主视图插入主模型所需的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的开发人员控制台监视客户端和服务器之间的流量,并且没有呼叫服务器刷新任何模型。

SubItem集合的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;
}

Backbone.js对嵌套集合/模型的支持不存在,它们不提供保存支持(请参阅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()工作,你需要在MainModel和ItemModel上重写toJSON,如:

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()

但是我按照自己的方式写下来,让非咖啡编写者更容易理解。


没有看完你的整个代码库,我想你可能会让你的结构稍微错误。 正常情况下,如果将el元素直接传递到视图中,我几乎不会将它传递给el。 该视图负责生成它自己的el。 渲染完成后,我将新的view.el插入到DOM中。 如下所示

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

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

在上述情况下,每个子视图都有一个主干对象。 如果你需要删除子视图,你不需要做一个选择器查询来找到它,你只需调用对象上的remove方法,它就知道如何从dom中删除它自己。

或者更具体地说,子视图处理自身上的点击事件,然后通过销毁它的相关模型然后调用remove

链接地址: http://www.djcxy.com/p/8465.html

上一篇: backbone.js collection not properly removing item in view

下一篇: Install Msmq using C#