12

为什么我必须创建一个完整的封闭原型才能让我的事件从我的视图中解除绑定?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');
        },

第一次渲染视图时,下拉菜单会正确打开和关闭,但在第二次渲染视图时,下拉菜单会解释每次点击两次,因此一旦打开,第二次点击就会关闭它。

4

1 回答 1

15

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


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

Derick 的文章非常棒地涵盖了整个问题。但是我可以添加我的两个位,解决您关于“为什么”它没有内置的问题。

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

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

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

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

不是直接的,我知道。但一般来说,无论哪个代码删除视图,如果需要,也应该清理事件绑定。通常,在良好的 MVC 架构中,视图可以在相应的模型或集合上设置事件观察器,然后根据发生的事件(例如,从相应模型中的“删除”事件)删除和清理自己。如果您想让您的视图的删除普遍“可检测”,一种方法是在您自己的视图原型中覆盖删除功能并触发其他人可以观察到的自定义事件。

于 2012-06-11T23:00:31.543 回答