backbone.js - 在 Backbone.js 或 Marionette.js 中重复创建和销毁 View 而不创建 "memory leak"

标签 backbone.js marionette

我怀疑我在backbone.js 中处理 View 的方式存在缺陷,以至于它会造成“内存泄漏”。

有一个 View 不断地被另一个自身的副本覆盖。新副本链接到不同的模型。

我正在通过设置 el 创建 View 并将其添加到它的父 View 中。创建 subview 时的选项。

正在发生的奇怪事情是,即使在旧 View 之上渲染了一个新 View ,当我单击“按钮”时,每个渲染的 childView 都会弹出一个警报,即使他们正在听的按钮应该消失了,他们响应新按钮。

我通过在旧 View 上调用函数以在添加新 View 之前停止监听事件来实现快速修复。但是这个问题的存在告诉我所有的旧观点都在徘徊如果用户不经常刷新页面,则会随着时间的推移减慢应用程序的速度。

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

}) 

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

当我单击“取消约会”按钮时,该函数会为该区域中显示的每个约会调用,即使我正在使用以下命令收听事件:events:{ 'click #cancel-button': 'on_button_click'}
我认为其他按钮、交互和其他控件都没有同样的问题,因为所有其他实际上是子约会 View 的 subview 而不是子约会 View 本身的实时 View

enter image description here

一个可能的修复?

做了一些搜索,这个修复看起来足够吗?

通常,我认为 removeData().unbind();remove()函数直接在 this.$el 上调用,但这在这里不起作用,我想是因为我使用 el 添加了 subview 创建时的选项 (el: this.ui.child_container)
var childView = Backbone.Marionette.ItemView.extend({
     ...
     // REAL FIX
     destroy_view: function(){
          this.undelegateEvents();

          this.$el.children().removeData().unbind();
          this.$el.children().remove();
     }

最佳答案

我认为你应该让你的父 View 成为一个 LayoutView (这只是一个增加了处理区域 iirc 功能的 ItemView),为你希望这个 subview 出现的位置定义了一个区域,然后执行:

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

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

(抱歉我用的是coffeescript,写起来比较快,但是翻译起来也很方便)。

Marionette 将处理所有事情:关闭您的旧 subview 、解除绑定(bind)事件等。

关于backbone.js - 在 Backbone.js 或 Marionette.js 中重复创建和销毁 View 而不创建 "memory leak",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35185984/

相关文章:

javascript - Backbone 集合获取导入不正确

javascript - Backbone Marionette 在模板示例中渲染模型

javascript - Jshint 告诉我们三元运算符中有一个警告

jquery - 如何在 JavaScript 中检测 OS X 的 Command-Shift-Click?

javascript - 主干 Marionette 复合 View 渲染模板

backbone.js - REST api 中的 Backbone 和复合模型 - 可能吗?

java - 带有spring或java的骨架.Marionette.js完整教程

backbone.js - 不带 id 的 Backbone 模型获取(用于显示登录用户的详细信息)

events - Backbone.js : change not firing on model. 更改()