在删除相应的DOM节点后,骨干视图是否会延续?

时间:2012-07-15 18:09:28

标签: backbone.js garbage-collection

我们的Web应用程序中有一些传统的非骨干代码。虽然我们将views附加到现有DOM元素,但仍有一些尚未重构的代码删除某些DOM元素,即删除调用不会通过视图但更多像jQuery调用$('#domID').remove();

我有一种唠叨的感觉,骨干视图可能像僵尸一样挂着,但我没办法看到它?这有害吗?我们是否应优先重构并通过视图删除所有删除内容并致电view.remove()view.unbind()进行正确删除?

如果独立删除DOM节点,视图是否会被垃圾收集?我想如果不是,它是否与某些事件有关,但如果不是这样呢?

1 个答案:

答案 0 :(得分:5)

只有在某个地方有引用时,视图才会停留。有四种杂散参考来源需要考虑:

  1. 绑定到模型和集合,即this.collection.on('reset', this.render)等。
  2. 通过视图events
  3. 绑定到DOM对象
  4. 通过直接$(...).on(...)调用绑定到DOM对象。
  5. 普通的旧变量引用,例如this.current_view = new V(...)
  6. (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()删除视图会很好想法。