0

我们的 Web 应用程序中有一些遗留的非主干代码。尽管我们附加views到现有的 DOM 元素,但仍有一些尚未重构的代码删除某些 DOM 元素,即删除调用不通过视图,但更像是 jQuery 调用$('#domID').remove();

我有一种唠叨的感觉,骨干视图可能像僵尸一样徘徊,但我没有办法看到它?这有害吗?我们是否应该优先考虑重构并让所有删除都通过视图和调用view.remove()进行view.unbind()正确删除?

如果单独删除 DOM 节点,视图是否会被垃圾回收?我想如果不是绑定到某个事件,但如果不是呢?

4

1 回答 1

5

只有在某处引用了该视图时,该视图才会持续存在。有四种杂散参考来源需要考虑:

  1. 绑定到模型和集合,即this.collection.on('reset', this.render)等。
  2. 通过视图的events.
  3. 通过直接$(...).on(...)调用绑定到 DOM 对象。
  4. 普通的旧变量引用,例如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()以删除视图将是一个好主意。

于 2012-07-15T19:09:22.290 回答