主干事件发射两次

时间:2012-06-11 21:24:48

标签: javascript backbone.js url-routing unbind

为什么我必须创建一个整体close prototype只是为了让我的事件从我的视图中解除绑定? Backbone不应该只是构建它吗?有没有办法检测何时删除视图?

我离开并回到视野后,我的骨干事件发生了两次。

        events : {
            "click #userDropdownButton > a" : "toggleUserDropdownMenu",
            "click" : "hideUserDropdownMenuIfClickedOutside"
        },

        el : "body",

        initialize : function() {
            this.render();
        },

        // Shows/hides the user dropdown menu
        toggleUserDropdownMenu : function() {
            if(!this.$el.find('#userDropdownButton > ul').is(':visible')) {
                this.showUserDropdownMenu();
            } else {
                this.hideUserDropdownMenu();
            }
            return false;
        },
        showUserDropdownMenu : function() {
            this.$el.find('#userDropdownButton').addClass('hover');
            this.$el.find('#userDropdownButton > ul').show();
            this.$el.find('#userDropdownButton > a .arrow-down').removeClass('arrow-down').addClass('arrow-up');
        },
        hideUserDropdownMenuIfClickedOutside : function() {
            if(this.$el.find('#userDropdownButton > ul').is(':visible')) {
                this.hideUserDropdownMenu();
            }
        },
        hideUserDropdownMenu : function() {
            this.$el.find('#userDropdownButton').removeClass('hover');
            this.$el.find('#userDropdownButton > ul').hide();
            this.$el.find('#userDropdownButton > a .arrow-up').removeClass('arrow-up').addClass('arrow-down');
        },

第一次呈现视图时,下拉列表会正确打开和关闭,但是第二次呈现视图时,下拉列表会将每次单击解释两次,因此一旦打开,第二次单击就会关闭它。

1 个答案:

答案 0 :(得分:15)

更新2013/05/01 :Backbone 0.9.9+添加了一些内置功能,以方便处理teh zomg问题(请参阅View.removeStopListening );但是你仍然需要通过调用其中一个来杀死你的僵尸。


为什么我必须创建一个完整的关闭原型才能让我的事件从我的视图中解除绑定?

Derick's article在覆盖整个问题时非常棒。但我可以添加我的两位,解决你的“为什么”它没有内置的问题。

由于Backbone事件委托的工作方式,如果视图超出范围(如果它们具有事件绑定),则不会对视图进行垃圾回收。这是因为它们绑定事件的对象 - 在绑定到Backbone对象事件的情况下是Backbone对象,或者在“events”回调的情况下是DOM事件系统 - 维护对视图函数的引用。

信不信由你,一些Backbone用户依赖于这种行为,并期望视图继续自动响应他们被告知要做的事件,即使他们已经完全超出范围。 (我已经看过几个这样做的教程。)这假设您永远不需要删除视图,或者视图可以响应事件并自行删除,因为您丢失了对它的任何引用,但是IMO,这个'只要你理解其含义,创造和忘记'功能就是好的。

mu is too short对UI事件提出了一个很好的观点。从DOM中删除el也应该删除委派的事件。对于绑定到模型或集合事件或其他Backbone对象的事件(任何对象都可以扩展Backbone Events原型),都不能这样说。您需要在链接到的文章中遵循Derick Bailey的建议,并在这些情况下手动关闭视图。与其他JS MVC框架相比,我不确定这是否是Backbone的弱点,我没有深入研究过其他人。

“有没有办法检测何时删除视图?”

不直接,我知道。但通常,删除视图的任何代码也应该在需要时清理事件绑定。通常,在良好的MVC架构中,视图可以在相应的模型或集合上设置事件观察者,然后移除&基于发生的事件清理它们自己(例如,来自相应模型的“移除”事件)。如果要使视图的删除普遍“可检测”,一种方法是覆盖您自己的视图原型中的remove函数,并触发其他人可以观察到的自定义事件。