骨干子视图和事件解除绑定

iab*_*abw 5 javascript performance event-handling subview backbone.js

几天我一直在使用Backbone,阅读设计模式以及你有什么.在阅读了大量资源之后,今天我在搞乱子视图.主要是这2个帖子 -

Derrick Bailey
http://lostechies.com/derickbailey/2011/09/15/zombies-run-managing-page-transitions-in-backbone-apps/

Ian Storm Taylor
http://ianstormtaylor.com/assigning-backbone-subviews订做偶数清洁剂/

这些和其他对于帮助我设置一些子视图并处理我认为正确模式的结束非常有用:

Backbone.View.prototype.close = function(){
    var ctx = this;
    _.each(ctx.subViews(), function(view) {
        view.close();
    });
    this.remove();
    this.unbind();
}
Run Code Online (Sandbox Code Playgroud)

这里没有问题,似乎做了我的预期.但我想测试一下,看看发生了什么.所以我停止在subViews上调用close并将我的渲染循环播放20,000次:

Backbone.View.prototype.close = function(){
    var ctx = this;
    _.each(ctx.subViews(), function(view) {
        //view.close();
    });
    this.remove();
    this.unbind();
}
Run Code Online (Sandbox Code Playgroud)

这里没有僵尸事件处理程序或DOM节点.这对我来说有点令人惊讶 - 我不是jQuery内部的专家,我希望至少还有来自子节点的事件处理程序.但我想因为我的子视图都包含在父视图中,它仍然被删除和未绑定,jQuery清除所有孩子.所以我停止了解除父元素的绑定:

Backbone.View.prototype.close = function(){
    var ctx = this;
    _.each(ctx.subViews(), function(view) {
        //view.close();
    });
    this.remove();
    //this.unbind();
}
Run Code Online (Sandbox Code Playgroud)

Chrome检查器中的事件处理程序计数仍然没有增加.

所以我的问题是:

当你需要以这种方式巧妙地处理事件解除绑定和子视图时,什么是"真实"的例子?是否超出了View的直接范围内的任何对象引用?是否只有父视图的$ el不包含您的子视图?

Pau*_*cke 3

当您从 DOM 中删除父视图时,jQuery 会清除子视图中挂接的所有 DOM 事件。 unbind()是 Backbone 的别名Events.off,它会删除您可能使用 挂接的任何事件myChildView.on('someEvent', ...)。例如,父视图可能会侦听您在子视图内触发的事件。如果您这样做,您将需要调用this.unbind()this.off()

现在 Backbone.Events(从 0.9.9 开始)已经有了listenTo()stopListening(),您可以考虑添加this.stopListening()到您的close(). 那么,在你看来,如果你使用了类似的东西,this.listenTo(this.model, ...)它们也会被妥善清理。

  • 我认为一切都已清理干净,因为您只连接了视图/子视图之间的事件。由于它们只是互相引用,因此它们被正确地 GC 了。当您有一个子视图监听具有较长生命周期的内容(可能是未关闭的模型或父视图)时,就会出现问题。另外,“view.remove()”已经调用了“stopListening()”,因此您不需要将其添加到“close”中。查看[本文](http://www.ibm.com/developerworks/web/library/wa-memleak/)。 (2认同)