gpt4 book ai didi

javascript - 不可能的 Backbone 僵尸

转载 作者:行者123 更新时间:2023-11-28 13:20:49 26 4
gpt4 key购买 nike

我现在大部分时间都在尝试调试我的 Backbone 多页面应用程序以摆脱“僵尸”,但不幸的是没有成功。在今天之前,我什至没有意识到我有一个僵尸问题。我做错了什么?

这是我的区域经理:

  var regionManager = (function() {
var currView = null;
var rm = {};

var closeView = function(view) {
if (view && view.close) {
view.close();
}
};

var openView = function(view) {
view.render();
if (view.onShow) {
view.onShow();
}
};

rm.show = function(view) {
closeView(currView);
currView = view;
openView(currView);
};

return rm;
})();

这是我的 View 清理功能:

  Backbone.View.prototype.close = function() {
if (this.onClose) {
this.onClose();
}

if (this.views) {
_.invoke(this.views, 'close');
}

// Unbind any view's events.
this.off();

// Unbind any model and collection events that the view is bound to.
if (this.model) {
this.model.off(null, null, this);
}

if (this.collection) {
this.collection.off(null, null, this);
}

// Clean up the HTML.
this.$el.empty();
};

我尝试将 View el 直接附加到 body 并在 View 清理函数中使用 this.remove(); (而不是使用常见的 el: $('#content') 向其附加元素,然后通过 this.$el.empty() 进行清理),但这也不起作用。

这可能与我的“全局事件”有关:

Backbone.Events.on('letterMouseDown', this.letterMouseDown, this);

但我用 onClose 函数来处理它们:

onClose: function() {
Backbone.Events.off('letterMouseDown');
}

最佳答案

我发现的一个问题是,您的 close 函数永远不会从 View 的 el 中删除事件委托(delegate)者。 View 的事件是通过使用 jQuery 的 on 的委托(delegate)者形式来处理的。将单个事件处理程序附加到 View 的 el。您的 close 会:

this.$el.empty();

但这只会删除内容和附加到该内容的任何事件处理程序,它对直接附加到 this.el 的处理程序没有任何作用。考虑这个最小的例子:

var V = Backbone.View.extend({
events: {
'click': 'clicked'
},
clicked: function() {
console.log('still here');
}
});
var v = new V({ el: '#el' });
v.close();

之后,单击#el 将会在控制台中抛出'still here',即使您认为 View 已完全清理。演示:http://jsfiddle.net/ambiguous/aqdq7pwm/

添加 undelegateEvents调用 close 应该可以解决这个问题。

<小时/>

一般建议:

  1. 不要使用老式的 onoff事件函数,使用listenTostopListening反而。 listenTo 跟踪监听器上的事件,以便以后更轻松地将它们全部删除。

  2. 将您的close简化为:

    Backbone.View.prototype.close = function() {
    if(this.onClose)
    this.onClose();
    if(this.views)
    _.invoke(this.views, 'close');
    this.remove();
    };
  3. 不要将 View 绑定(bind)到现有的el。让 View 创建(并拥有)自己的 el 并让调用者将该 el 放入通常的容器中:

    var v = new View();
    container.append(v.render().el);

    模式。如果您必须附加到现有的el,那么 View 应该使用标准实现的稍微修改版本覆盖remove:

    remove: function() {
    this.$el.empty(); // Instead of removing the element.
    this.undelegateEvents(); // Manually detach the event delegator.
    this.stopListening();
    return this;
    }

关于javascript - 不可能的 Backbone 僵尸,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33200663/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com