我的页面中有一大块表示视图的标记,以及与该视图关联的 JS 控制器函数。(这些是 Angular,但我认为这并不重要。)控制器代码监听从应用程序其他地方触发的自定义事件,并使用一些特定于控制器的逻辑处理该事件。
我的问题是控制器的事件处理程序被附加太多次:每次重新激活视图时都会附加它,导致每次触发自定义事件时处理程序都会运行多次。我只希望处理程序在每个事件中运行一次。
我尝试.off()
在绑定之前使用取消绑定处理程序;我试图.one()
确保处理程序只运行一次;我$.proxy()
在阅读了它与.off()
这里的交互后尝试过。
这是我的代码的草图:
// the code inside this controller is re-run every time its associated view is activated
function MyViewController() {
/* SNIP (lots of other controller code) */
function myCustomEventHandler() {
console.log('myCustomEventHandler has run');
// the code inside this handler requires the controller's scope
}
// Three variants of the same misbehaving event attachment logic follow:
// first attempt
$('body').off('myCustomEvent', myCustomEventHandler);
$('body').on('myCustomEvent', myCustomEventHandler);
// second attempt
$('body').one('myCustomEvent', myCustomEventHandler);
// third attempt
$('body').off('myCustomEvent', $.proxy(myCustomEventHandler, this));
$('body').on('myCustomEvent', $.proxy(myCustomEventHandler, this));
// all of these result in too many event attachments
};
// ...meanwhile, elsewhere in the app, this function is run after a certain user action
function MyEventSender() {
$('body').trigger('myCustomEvent');
console.log('myCustomEvent has been triggered');
};
在我的应用程序中单击并切换到麻烦的视图五次后,然后执行运行的操作MyEventSender
,我的控制台将如下所示:
myCustomEvent has been triggered
myCustomEventHandler has run
myCustomEventHandler has run
myCustomEventHandler has run
myCustomEventHandler has run
myCustomEventHandler has run
我怎样才能让它看起来像这样:
myCustomEvent has been triggered
myCustomEventHandler has run
???