2010-03-19 107 views
5

我正在尋找一種方法來添加一個EventListener,它會在第一次啓動後自動刪除它,但我無法想象這樣做的方式,我想要的方式。AS3-只發生一次的事件監聽器

我發現這個功能(here):但

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); 


有沒有人知道如何做到這一點NE?
任何幫助將非常感謝。


(我知道羅伯特·彭納的Signals可以做到這一點,但我不能使用它們,因爲這將意味着大量的代碼重寫,我買不起我的當前項目)

+0

嘗試使用[信號庫(https://github.com/robertpenner/as3-signals/wiki)。 – 2011-10-10 15:04:22

回答

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 
      } 
     ) 
    ) 
+0

這是一個很好的伎倆,我沒有想到,謝謝! –

+0

沒問題;)關閉確實非常方便。我正在建造一個裝滿封閉物和全局功能技巧的包,看看它會走到哪裏。 –

+0

你將如何手動刪除這樣一個監聽器,因爲你添加的監聽器是一個匿名函數?如果你不能手動刪除它,遲早你會遇到一個bug。 – 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); 
+0

我不能使用繼承,因爲AS3不允許多繼承,並且我的大多數類已經擴展了另一個繼承。我想把這個函數放在一個外部的.as文件中,我將它包含在所有的類中,但是我想知道是否有更好的方法來實現這個功能。 –

+0

我也可以直接在Flex SDK中將函數添加到UIComponent類中;這將解決我的問題,但它更醜陋=/ –

1
functionadd.addEventListener(COMPLETE,functionremove); 

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