在Backbone.js或Marionette.js中反复创建和销毁视图,而不会产生"内存泄漏"

时间:2016-02-03 19:30:18

标签: backbone.js marionette

我怀疑我在backbone.js中处理视图的方式存在缺陷,因为它正在创建一个"内存泄漏"。

有一个视图不断被另一个副本覆盖。新副本链接到不同的模型。

我在创建子视图时通过设置el选项来创建视图并将其添加到其父视图中。

正在发生的奇怪事情是,即使在旧视图的顶部渲染了一个新视图,当我点击"按钮"每次呈现的每个childView都会弹出一个警告,即使他们正在收听的按钮消失了,它们也会响应新的按钮。

我通过调用旧视图上的函数来实现快速修复,以便在添加新视图之前停止侦听事件。但是存在这个问题告诉我所有旧视图都在闲置,如果用户不经常刷新页面,将会减慢应用程序的速度。

var parent = new (Backbone.Marionette.ItemView.extend({
     ui:{
          child_container: '#child-container'
     },
     onRender: function(){
          // Listen to outside event
          ...
     }
     on_Outside_Event: function(new_model){
          // Quick fix prevents multiple alerts popping up for every child view when "button" is pressed
          this.child_view.destroy_view(); 

          // New child view is created and rendered on top of the one that was there before
          this.child_view = childView({
               el:    this.ui.child_container,  // <-- Is this the problem?
               model: new_model
          })
          this.child_view.render();
     }
}))();

var childView = Backbone.Marionette.ItemView.extend({
     events:{
          'click button': 'on_click_button'
     },
     on_click_button: function(){

          // Alert pops up once for every view that was ever displayed.
          alert('Button clicked');  
     },
     // QUICK FIX
     destroy_view: function(){
          this.undelegateEvents();
     }

}) 

如果这有用,这里是实际应用程序的屏幕截图。约会日历在右边。问题子视图 - 用户想要查看的单个约会视图位于左侧。

当我点击&#34;取消约会&#34;按钮,即使我正在使用:events:{ 'click #cancel-button': 'on_button_click'}

收听事件,也会为该区域中显示的每个约会调用该函数

其他任何按钮,交互和其他控件都没有同样的问题,我假设因为所有其他人实际上都是子视图子视图的子视图,而不是子视图预约视图本身

enter image description here

可能的解决方法?

进行了一些搜索,这个修复程序是否足够?

通常情况下,我认为removeData().unbind();remove()函数直接在this.$el上调用,但这不起作用,我想是因为我使用{{1添加了子视图创建它时的选项(el

el:    this.ui.child_container

1 个答案:

答案 0 :(得分:2)

我认为你应该让你的父视图成为一个LayoutView(它只是一个具有处理区域iirc的附加功能的ItemView),有一个区域定义了你希望这个子视图出现的位置,然后执行:< / p>

  Parent = Backbone.Marionette.LayoutView.extend
    regions:
      child: "#child-container"

    on_Outside_Event: ->
      childView = new ChildView(...)
      @getRegion("child").show(childView)

(抱歉,我使用了coffeescript,编写速度更快,但你可以轻松翻译)。

Marionette将处理所有事情:关闭旧的孩子观点,解除绑定事件等等。