DelegateEvents:从集合中删除模型时未删除子项目视图

时间:2013-08-30 12:42:28

标签: backbone.js javascript-events marionette backbone-views

我有一个可以在布局区域中交换的集合视图ItineraryEditorView。 使用region.show交换相同的collectionView实例,而不是每次都为collectioView创建新实例。集合上的render方法调用delegateEvents()方法。

    ItineraryEditorView = Marionette.CollectionView.extend({
    tagName: "div",
    emptyView: EmptyItineraryDayView,
    itemView: ItineraryDayView,
    initialize: function (options) {            
    },  
    render: function() {
        Marionette.CollectionView.prototype.render.apply(this);
        this.delegateEvents();
    },
});

视图将通过关闭区域进行换出:

plannerLayout.itineraryEditorRegion.close();

在视图中交换:

itineraryEditorView.delegateEvents();
plannerLayout.itineraryEditorRegion.show(itineraryEditorView);

通过监听从itemView到collectionView的冒泡事件来完成模型的删除(在这里没有问题)

itineraryEditorView.on("itemview:delete:day", function(childView, model)    {
    days.remove(model); //days coll is passed in to coll view on instance creation
    holiday.save();
});

我希望这足以确保在从基础天集合中删除模型时删除/关闭集合视图中的子itemView。我可以看到该集合实际上已被修改并保存在服务器上,但集合视图不会被更改。 在第一次交换集合视图之前,这种情景可行。 柯尔。在我重新访问另一个选项卡并返回此选项卡后,视图会自动更新(因此整个集合都会呈现 - 确认更改/删除)

解决此问题的最佳方法是什么?如果我重新创建集合视图的实例,它确实会导致代码中的其他“on”句柄松动。

1 个答案:

答案 0 :(得分:0)

无需手动调用delegateEvents - Backbone在视图的构造函数中执行此操作。当您关闭该区域时,该区域将关闭您的视图,删除所有内部引用并解除所有事件的绑定,为垃圾收集做好准备。视图已close()'后,不应再次使用。解决问题的方法应该是new另一个ItineraryEditorView实例并将其传递到show上的区域。

此外,在致电region.close()之前,无需致电region.show(view); show做的第一件事就是close()当前视图(如果有的话)。我建议修改你的代码如下:

ItineraryEditorView = Marionette.CollectionView.extend({
    // tagName: "div", // <-- unnecessary as written - default tag

    emptyView: EmptyItineraryDayView,

    itemView: ItineraryDayView

    // this empty override is unnecessary as written - recommend removing it
    // initialize: function (options) {           
    // },

    // this override is unnecessary as written - remove it:
    // render: function() {
    //     Marionette.CollectionView.prototype.render.apply(this);
    //     this.delegateEvents();
    // },
});

...

// plannerLayout.itineraryEditorRegion.close(); <-- delete this line; it's not needed
// itineraryEditorView.delegateEvents();        <-- ditto

从原始帖子编辑

// define a delegate to handle events shared across multiple instances of the view:
function handleDeleteChild(childView, model) {
    days.remove(model); //days coll is passed in to coll view on instance creation
    holiday.save();
});

// create the ItineraryEditorView
// NOTE: As written this will likely conflict with your current code;
//       update as required
var itineraryEditorView = new ItineraryEditorView(options);

// bind event listeners to it
itineraryEditorView.on("itemview:delete:day", handleDeleteChild);

// show it
plannerLayout.itineraryEditorRegion.show(itineraryEditorView);