在Backbone.js或Marionette.js中重复创建和销毁视图,而不创建“;“内存泄漏”;
我怀疑我在backbone.js中处理视图的方式存在缺陷,导致“内存泄漏” 有一个视图不断被自身的另一个副本覆盖。新副本链接到其他模型 在创建子视图时,我通过设置在Backbone.js或Marionette.js中重复创建和销毁视图,而不创建“;“内存泄漏”;,backbone.js,marionette,Backbone.js,Marionette,我怀疑我在backbone.js中处理视图的方式存在缺陷,导致“内存泄漏” 有一个视图不断被自身的另一个副本覆盖。新副本链接到其他模型 在创建子视图时,我通过设置el选项来创建视图并将其添加到父视图中 发生的奇怪事情是,即使在旧视图的上方渲染新视图,当我单击“按钮”时,每次渲染的每个子视图都会弹出一个警报,即使他们听到的按钮应该消失,他们也会响应新按钮 我已经通过调用旧视图上的函数来实现了一个快速修复,在添加新视图之前停止侦听事件。但是这个问题的存在告诉我,所有的旧视图都挂起了,如果用户没有足够
el
选项来创建视图并将其添加到父视图中
发生的奇怪事情是,即使在旧视图的上方渲染新视图,当我单击“按钮”时,每次渲染的每个子视图都会弹出一个警报,即使他们听到的按钮应该消失,他们也会响应新按钮
我已经通过调用旧视图上的函数来实现了一个快速修复,在添加新视图之前停止侦听事件。但是这个问题的存在告诉我,所有的旧视图都挂起了,如果用户没有足够频繁地刷新页面,就会随着时间的推移减慢应用程序的速度
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();
}
})
我认为您应该将父视图设置为LayoutView(这只是一个ItemView,添加了处理区域iirc的功能),为希望此子视图出现的位置定义一个区域,然后执行以下操作:
Parent = Backbone.Marionette.LayoutView.extend
regions:
child: "#child-container"
on_Outside_Event: ->
childView = new ChildView(...)
@getRegion("child").show(childView)
(对不起,我用了coffeescript,它写起来更快,但你可以很容易地翻译)
木偶将处理所有事情:关闭旧的子视图、解除绑定事件等。当我第一次开始使用木偶时,我使用了几次布局,但我认为我不太了解它们。这个应用程序很大,有很多级别的父视图和子视图。是否有时可以嵌套布局?如果我理解正确,重新渲染布局通常是不合适的(反正我几乎从不重新渲染视图)?什么时候使用ItemView而不是布局?谢谢布局是非常有用的,而且它们是可嵌套的,这是使它们变得伟大的原因之一。木偶文件提到它们可以随意嵌套。但你是对的,你应该避免重新渲染一个嵌套布局的大“树”。但通常有很多方法可以避免这种情况,只需将子视图绑定到它们的模型或任何正在更改的对象,并使它们自己重新渲染即可。例如,在您的示例中,为什么不使用新模型中的数据更新子视图模型,强制其重新渲染?我不会用新信息更新子视图模型,因为每个模型只有一个副本。一个模型有时位于多个视图后面。在本例中,左侧的约会详细信息视图和右侧日历中的约会视图使用相同的模型。因此,例如,在“详细信息”视图中更改约会的“开始时间”时,约会在日历中的位置实际上会随着用户的键入而改变。在将来,我想从服务器添加模型的推送更新。当这种情况发生时,所有视图都会更新。顺便说一句,我不认为单模型多视图架构是从单个模型更新多个视图的唯一方法。我可以创建一个事件系统来更新单视图单模型体系结构中模型的所有副本。现在的方式正是我设计应用程序时最有意义的方式。不过,在开发的这个时候,切换到一个模型一个视图的体系结构是非常重要的。顺便说一句,我喜欢pathofmaps的设计。我明白了,如果模型是为了表示不同的约会,那么不更新模型肯定是有意义的。那么布局方法是正确的,您只需要将父视图作为布局,并在适当的区域替换当前子视图。
Parent = Backbone.Marionette.LayoutView.extend
regions:
child: "#child-container"
on_Outside_Event: ->
childView = new ChildView(...)
@getRegion("child").show(childView)