Backbone Marionette - 布局视图僵尸

Backbone Marionette - Layout View Zombies

我的 Backbone Marionette 应用程序出现问题,我的子视图没有被完全破坏。您如何正确销毁要替换为另一个 layout/item 视图的嵌套布局视图?

我在 Marionette documentation on destroying layout views 的印象中,当我设置一个区域来显示新视图时,旧视图被破坏了。但是,通过 vent 触发的事件仍然可以在据称已被破坏的旧视图中看到。

我在这里创建了这个问题的示例:https://jsfiddle.net/dhardin/5j3x2unx/

我认为问题出在我的路由器上:

App.Router = Marionette.AppRouter.extend({
  routes: {
    '': 'showView1',
    'view1': 'showView1',
    'view2': 'showView2'

  },
  showView1: function() {
    var view1 = new App.View1();
    App.Layout.mainRegion.empty();
    App.Layout.mainRegion.show(view1);
  },
  showView2: function() {
    var view2 = new App.View2();
    App.Layout.mainRegion.empty();
    App.Layout.mainRegion.show(view2);
  }
});

我的理解不需要App.Layout.mainRegion.empty(),因为在区域经理 show() 函数。 要查看问题,请通过导航导航到另一个视图,然后单击按钮。您将看到针对旧视图和新视图都触发了警报。

回到我的 marionette 之前的应用程序中,我遵循了一种清理模式来避免讨论的这些内存泄漏 here

基本上,当我的应用更改为新视图时,我显示的视图会调用以下函数:

Backbone.View.prototype.close = function(){
  this.remove();
  this.unbind();
}

如果您需要任何其他信息,请告诉我。提前致谢!

对于此类情况,您应该利用 onDestroy 功能来执行 Marionette 提供的额外清理工作。 Marionette 在替换或删除视图时自动调用 onDestroy

onDestroy: function() {
     App.vent.off('ButtonClicked', this.onButtonClicked, this);
  }

来自 Marionette 文档:

By providing an onDestroy method in your view definition, you can run custom code for your view that is fired after your view has been destroyed and cleaned up. The onDestroy method will be passed any arguments that destroy was invoked with. This lets you handle any additional clean up code without having to override the destroy method.

在此处查看工作 fiddle:https://jsfiddle.net/ocfn574a/

请注意,我确实在您的路由配置中更新了一个拼写错误:'showVeiw1' -> 'showView1'

您应该使用 this.listenTo(App.vent, 'ButtonClicked', this.onButtonClicked) 而不是 App.vent.on('ButtonClicked', this.onButtonClicked, this); 这样 marionette 会在视图被销毁时注意关闭所有侦听器并且您不需要显式处理 onDestory取消监听器的事件。查看更新后的 fiddle here。 所以基本上你的路由器没有问题但是注册监听器有问题因为监听器不存在于视图对象中它没有被注销。