我试过这样做:
root.addEventListener("click", function () { navigateToURL(ClickURLRequest,"_self"); });
它确实添加了事件监听器.我喜欢使用闭包,因为它们在这种情况下效果很好,
但是,删除事件监听器需要引用原始函数,因为我使用了匿名闭包,它不起作用,我试过:
root.removeEventListener("click", function () { navigateToURL(ClickURLRequest,"_self"); });
以及:
root.removeEventListener("click", function () {} );
我发现它的唯一方法就是抛弃匿名闭包并将事件监听器指向一个预先存在的函数:
function OnClick (e:Event) { navigateToURL(ClickURLRequest,"_self"); } root.addEventListener("click", OnClick); root.removeEventListener("click", OnClick);
有没有人知道如何使用匿名闭包事件处理程序,同时仍然保留删除它们的能力?
这是删除我在生产项目中使用的事件侦听器的一般方法
addEventListener ( Event.ACTIVATE, function(event:Event):void { (event.target as EventDispatcher).removeEventListener(event.type, arguments.callee) } )
正如已经建议的那样,您可以从闭包本身中删除闭包中的闭包.这是通过使用arguments.callee完成的:
myDispatcher.addEventListener("click", function(event:Event):void { IEventDispatcher(event.target).removeEventListener(event.type, arguments.callee); // Whatever else needs doing goes here });
这将有效地将闭包转变为事件的一次性监听器,只需在事件触发后自行分离.虽然语法冗长,但对于那些真正只触发一次(或者你只关心一次)的事件来说,它是一种非常有用的技术,比如Flex中的"creationComplete".我一直在下载数据时使用它,因为我认为内联回调代码使得它更容易理解.这就像隐藏异步一样:
myLoader.addEventListener("complete", function(event:Event):void { /* Even though the load is asynchronous, having the callback code inline * like this instead of scattered around makes it easier to understand, * in my opinion. */ });
但是,如果您想多次收听该事件,由于显而易见的原因,这将不会非常有效.在这种情况下,您需要在某处存储对闭包的引用.方法是ActionScript中的任何其他对象,可以传递.因此,我们可以将代码更改为:
var closure:Function; myDispatcher.addEventListener("click", function(event:Event):void { closure = arguments.callee; // Whatever else needs doing goes here });
当您需要删除事件侦听器时,请使用'closure'引用,如下所示:
myDispatcher.removeEventListener("click", closure);
显然,这是一个抽象的例子,但使用这样的闭包非常有用.但它们确实有缺点,例如效率低于命名方法.另一个缺点是,如果您需要,您实际上必须存储对闭包的引用.必须注意保持该参考的完整性,就像使用任何其他变量一样.
因此,尽管不同的语法可能有其用途,但它并不总是最佳解决方案.这是一种苹果和橘子的东西.