javascript 主干事件触发两次
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10987738/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Backbone events firing twice
提问by Garrett
Why must I create a whole close prototypejust to have my events unbinded from my view? Shouldn't Backbone just build that in? Is there a way to detect when a view is being removed?
为什么我必须创建一个完整的关闭原型才能让我的事件从我的视图中解脱出来?Backbone 不应该直接构建它吗?有没有办法检测视图何时被删除?
My backbone events fire twice after I navigate away and back to the view.
在我离开并返回视图后,我的主干事件触发了两次。
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');
},
The first time the view is rendered, the dropdown opens and closes properly, but on the second time the view is rendered, the dropdown interprets every click twice, so as soon as it opens, the second click closes it.
第一次渲染视图时,下拉菜单会正确打开和关闭,但是在第二次渲染视图时,下拉菜单会解释每次单击两次,因此一旦打开,第二次单击将关闭它。
回答by Ben Roberts
Update 2013/05/01: Backbone 0.9.9+ has added some built-in functionality to facilitate easy dealing with teh zomg problem (see View.removeand StopListening); but you'll still need to kill your zombies by calling one of these.
2013 年 5 月 1 日更新:Backbone 0.9.9+ 添加了一些内置功能以方便处理 zomg 问题(参见View.remove和StopListening);但是你仍然需要通过调用其中一个来杀死你的僵尸。
Why must I create a whole close prototype just to have my events unbinded from my view?
为什么我必须创建一个完整的关闭原型才能让我的事件从我的视图中解脱出来?
Derick's articleis awesome at covering this whole issue. But I can add my two bits, addressing your question of "why" its not built in.
Derick 的文章在涵盖整个问题方面非常出色。但是我可以添加我的两个部分,解决您关于“为什么”没有内置的问题。
Because of the way that Backbone event delegation works, views won't be garbage collected when they go out of scope if they have event bindings. This is because the objects whose events they bind to--Backbone objects, in the case of binding to Backbone object events, or the DOM event system in the case of "events" callbacks--maintain references to the view's functions.
由于 Backbone 事件委托的工作方式,如果有事件绑定,视图在超出范围时不会被垃圾收集。这是因为它们绑定到其事件的对象——Backbone 对象,在绑定到 Backbone 对象事件的情况下,或在“事件”回调的情况下的 DOM 事件系统——维护对视图函数的引用。
Believe it or not, some Backbone users rely on this behavior and expect views to continue auto-responding to events like they were told to do, even if they have gone completely out of scope. (I've seen several tutorials that do this. ) This assumes that you never need to remove the view, or that the view can respond to events and remove itself, since you've lost any reference to it, but IMO, this 'create and forget' functionality is nice as long as you understand the implications.
信不信由你,一些 Backbone 用户依赖这种行为,并期望视图继续像他们被告知的那样自动响应事件,即使它们已经完全超出范围。(我看过几个这样做的教程。)这假设您永远不需要删除视图,或者视图可以响应事件并自行删除,因为您已经丢失了对它的任何引用,但是 IMO,这个 '只要您了解其含义,就可以创建并忘记“功能”。
mu is too short
makes a good point about UI events. Removing the el from the DOM should remove the delegated events as well. The same can't be said for binding to model or collection events or to other Backbone objects' events (any object can extend the Backbone Events prototype). You'll need to follow Derick Bailey's advice in the article you link to and manually close the view in these cases. I am not sure if this is a weakness of Backbone compared to other JS MVC frameworks, I haven't tried others as in depth.
mu is too short
很好地说明了 UI 事件。从 DOM 中删除 el 也应该删除委托的事件。对于绑定到模型或集合事件或其他 Backbone 对象的事件(任何对象都可以扩展 Backbone Events 原型),则不能说相同。在这些情况下,您需要遵循您链接到的文章中的 Derick Bailey 的建议并手动关闭视图。我不确定这是否是 Backbone 与其他 JS MVC 框架相比的弱点,我还没有深入尝试其他框架。
"Is there a way to detect when a view is being removed?"
“有没有办法检测视图何时被移除?”
Not directly, that I'm aware of. But generally, whichever code is removing view should also clean up the event bindings if it needs done. Often, in good MVC architectures, views can set up an event observer on a corresponding model or collection, and then remove & cleanup themselves based on the event occuring (e.g., the "remove" event from a corresponding model). If you want to make your views' removal universally "detectable", one way would be to override the remove function in your own view prototype and trigger a custom event that can be observed by others.
不是直接的,我知道。但一般来说,如果需要删除视图,任何代码都应该清理事件绑定。通常,在良好的 MVC 架构中,视图可以在相应的模型或集合上设置事件观察器,然后根据发生的事件(例如,从相应模型中“删除”事件)移除和清理自身。如果您想让您的视图的删除普遍“可检测”,一种方法是在您自己的视图原型中覆盖 remove 函数并触发一个可以被其他人观察到的自定义事件。