AS3 - 仅触发一次的事件监听器

5
我正在寻找一种添加EventListener的方式,它会在第一次触发后自动删除自己,但是我无法找到我想要的方式来实现这个功能。
我找到了这个函数(在这里):
public class EventUtil
{
    public static function addOnceEventListener(dispatcher:IEventDispatcher,eventType:String,listener:Function):void
    {
         var f:Function = function(e:Event):void
         {
              dispatcher.removeEventListener(eventType,f);
              listener(e);
          }
          dispatcher.addEventListener(eventType,f);
    }
}


但是不必写成:

EventUtil.addOnceEventListener( dispatcher, eventType, listener );

我想以通常的方式使用它:

dispatcher.addOnceEventListener( eventType, listener );


有人有想法如何实现这个吗?
非常感谢任何帮助。


(我知道Robert Penner的Signals可以做到这一点,但由于这将意味着我无法为当前项目承受大量代码重写,因此我不能使用它们)


尝试使用Signals Library - user987930
3个回答

11

我发现最干净的方法是定义一个全局函数(在一个名为removeListenerWhenFired.as的文件中),而不使用静态或混淆代码:

package your.package
{
    import flash.events.Event;
    import flash.events.IEventDispatcher;

    public function removeListenerWhenFired(callback:Function, useCapture:Boolean = false):Function
    {
        return function (event:Event):void
        {
            var eventDispatcher:IEventDispatcher = IEventDispatcher(event.target)
            eventDispatcher.removeEventListener(event.type, arguments.callee, useCapture)
            callback(event)
        }
    }
}
然后你可以像这样监听事件:
import your.package.removeListenerWhenFired

// ... class definition

    sprite.addEventListener(MouseEvent.CLICKED, 
        removeListenerWhenFired(
            function (event:MouseEvent):void {
                ... do something
            }
        )
    )

没有问题 ;) 闭包确实非常方便。我正在构建一个充满闭包和全局函数技巧的工具包,看看它们将会带来什么。 - BefittingTheorem
你如何手动删除这样的监听器,因为你添加的监听器是一个匿名函数?如果无法手动删除它,那么迟早会遇到问题。 - chichilatte

2

我没有尝试过,但你可以将EventUtil静态方法转换为标准方法,并在你的对象中扩展该类。

public class OnceEventDispatcher
{
    public function addOnceEventListener(eventType:String,listener:Function):void
    {
         var f:Function = function(e:Event):void
         {
              this.removeEventListener(eventType,f);
              listener(e);
          }
          this.addEventListener(eventType,f);
    }
}

public class Example extends OnceEventDispatcher
{


}

var ex:Example = new Example();
ex.addOnceEventListener(type, func);

由于AS3不允许多重继承,所以我无法使用继承。而且我的大部分类已经继承了其他类。我考虑将这个函数放在一个外部的.as文件中,并在所有的类中引入它,但我想知道是否有更好的方法来实现这个。 - Zed-K
我也可以直接在Flex SDK中向UIComponent类添加该函数;这将解决我的问题,但这样做甚至更加丑陋 =/ - Zed-K

1
functionadd.addEventListener(COMPLETE,functionremove);

functionremove()
{
    runevent();
    functionadd.removeEventListener(COMPLETE,functionremove);
}
function runevent()
{
   trace('Hello');
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接