我正在扩展Backbone.View以支持子视图,我有一个addSubview
方法,只是将一个Backbone视图添加到哈希。很容易。我现在正试图这样做,只要你destroy
一个视图它就会破坏所有的子视图。我认为这也很容易,但我的方法是无限循环:
destroy: function () {
debugger;
// Call destroy on all subviews. If the subviews have subviews they'll
// be destroyed as well
for (var v in this._subviews) {
this._subviews[v].destroy();
}
// Instead of calling `delete` on every view we wipe everything out after
// we're done destroying all the views
this._subviews = {};
// Finally, since all the subviews are destroyed it's safe to destroy
// this view
this.remove();
},
发生的情况是,调试器是第一次调用而this
是调用destroy
调用(右),第二次调用第一次子视图(右),第三次调用 - ∞它仍然保持调用第一个子视图。它一步一步地玩:
this._subviews[v].destroy();
行和v
==第一个子视图这就是全部。它会永远重复。任何想法或建议?
答案 0 :(得分:3)
这里发生的事情是object
调用_subviews
存储在Foo.View
的原型上(Backbone的extend
方法正在执行此操作)并因此被共享通过 Foo.View
的所有实例。这是设置的地方:
Foo.View = Backbone.View.extend({
_subviews: {}, // right here
这会导致问题,因为当您添加第一个子视图时,会将其添加到this._subviews
。由于_subviews
对象由View
的每个实例共享,因此当您将子视图添加到子视图时,所有其他视图都认为View
是他们自己的子视图。
具体来说,这里发生的是当您致电.destroy()
时,在您的循环顶部调用所有子视图上的destroy()
会意外地再次在同一个视图上调用destroy()
。在循环之后的几行之前,_subviews
变量不会被清除:
// Instead of calling `delete` on every view we wipe everything out after
// we're done destroying all the views
this._subviews = {};
因此,它变得无限,因为它一遍又一遍地遍历同一个_subviews
列表,卡在第一个似乎永远不会被删除的地方。
为了让世界满意,_subviews
对象应该是每个View
的实例变量,而不是View
原型。为此,您应该为每个新View
分配一个新的:
initialize: function () {
this._subviews = {};
}
答案 1 :(得分:2)
问题是_subviews
在父Foo
和子Foo
实例之间被共享。修复方法是为每个实例初始化_subviews
:
initialize: function () {
this._subviews = {};
}
尝试以面向类的风格使用Javascript时,这是一个非常常见的问题。