我们的Web应用程序中有一些传统的非骨干代码。虽然我们将views
附加到现有DOM元素,但仍有一些尚未重构的代码删除某些DOM元素,即删除调用不会通过视图但更多像jQuery调用$('#domID').remove();
我有一种唠叨的感觉,骨干视图可能像僵尸一样挂着,但我没办法看到它?这有害吗?我们是否应优先重构并通过视图删除所有删除内容并致电view.remove()
和view.unbind()
进行正确删除?
如果独立删除DOM节点,视图是否会被垃圾收集?我想如果不是,它是否与某些事件有关,但如果不是这样呢?
答案 0 :(得分:5)
只有在某个地方有引用时,视图才会停留。有四种杂散参考来源需要考虑:
this.collection.on('reset', this.render)
等。events
。$(...).on(...)
调用绑定到DOM对象。this.current_view = new V(...)
。 (1)通常由视图的remove
方法处理,您必须自己调用remove
,Backbone或jQuery中没有任何内容可以为您执行此操作。例如:http://jsfiddle.net/ambiguous/e574Z/
(2)很容易。骨干视图使用单个delegate
调用将视图的事件绑定到视图的el
。因此,如果您通过简单的el
删除视图的$(x).remove()
,则事件参考会消失。但是,如果您将不同的观点附加到同一el
,则需要致电undelegateEvents
以分离delegate
;这通常是在remove
方法中完成的:
remove: function() {
this.undelegateEvents();
return this;
}
但是,你必须再次在某处调用remove
。
(3)很少见,但有时需要窗口滚动事件,对话框的正文点击事件以及类似的事情。当然,你必须自己清理它们,因为Backbone无法知道你背后所做的是什么,你绑定的元素将在视图的el
之外(或者你是在(2))。你会在哪里清理这些?当然是remove
方法。
(4)一如既往地取决于您。通常,这种事情是这样处理的:
if(this.current_view)
this.current_view.remove();
this.current_view = null;
是的,再次remove
。
所以,如果您拥有的是(2)之类的东西,那么$('#domID').remove();
就可以了,不应该留下任何僵尸;实际上,默认的remove
实现只是this.$el.remove()
,文档也说明了这一点:
删除
view.remove()
从DOM中删除视图的便捷功能。相当于调用
$(view.el).remove();
但是,你可能还有一些事情,例如(1),所以添加/更新所有remove
方法,调用view.remove()
删除视图会很好想法。