【问题标题】:Backbone Subviews and Event Unbinding主干子视图和事件解除绑定
【发布时间】:2013-01-30 22:07:29
【问题描述】:

我已经和 Backbone 一起工作了几天,阅读了设计模式以及你有什么。在阅读了一堆资源之后,今天我正在搞乱子视图。主要是这两个帖子-

德里克·贝利
http://lostechies.com/derickbailey/2011/09/15/zombies-run-managing-page-transitions-in-backbone-apps/

伊恩·斯托姆·泰勒
http://ianstormtaylor.com/assigning-backbone-subviews-made-even-cleaner/

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

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

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

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

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

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

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

所以我的问题是:

什么是您需要以这种方式巧妙地处理事件解除绑定和子视图的“真实”示例?它是您的视图直接范围之外的任何对象引用吗?仅当您的子视图不包含在父视图的 $el 中?

【问题讨论】:

    标签: javascript performance backbone.js event-handling subview


    【解决方案1】:

    当你从 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, ...) 之类的东西,它们也会被正确清理。

    【讨论】:

    • 谢谢保罗。我更多地使用了事件绑定,试图更全面地理解它。你说“父视图可能会监听你在子视图中触发的事件。如果你这样做了,你需要调用this.unbind()或this.off().”我想我第一次没有正确创建这些,所以我在视图和子视图中绑定了一些处理程序(以响应它们的渲染)并且没有清理它们,但仍然没有僵尸事件。是否有您的答案未包含的细节,或者您可以提供的具体示例?
    • 我认为这一切都已清理干净,因为您只在视图/子视图之间连接了事件。由于它们只相互引用,因此它们被正确地 GC。一个问题是当你有一个子视图来监听寿命更长的东西(可能是一个模型或未关闭的父视图)。此外,view.remove() 已经调用了stopListening(),因此您无需将其添加到close。签出this article。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-09-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多