2010-03-19 17 views
5

Sto cercando un modo per aggiungere un EventListener che si rimuoverà automaticamente dopo la prima accensione, ma non riesco a capire come farlo nel modo in cui voglio .AS3 - Listener di eventi che si attiva solo una volta

ho trovato questa funzione (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); 
    } 
} 


Ma invece di dover scrivere:

EventUtil.addOnceEventListener(dispatcher, eventType, listener); 

vorrei usarlo solito modo:

dispatcher.addOnceEventListener(eventType, listener); 


Qualcuno ha un'idea di come potrebbe essere questo? ne?
Qualsiasi aiuto sarebbe molto apprezzato.


(so che è Signals Robert Penner può fare questo, ma io non li può usare poiché significherebbe un sacco di codice riscrittura che non mi posso permettere per il mio progetto in corso)

+0

provare a utilizzare il [Biblioteca Segnali] (https://github.com/robertpenner/as3-signals/wiki). –

risposta

11

trovo il modo più pulito senza l'utilizzo di statica o rovinare il codice con il rumore è quello di definire una funzione globale (in un file chiamato removeListenerWhenFired.as) in questo modo:

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

allora si può ascoltare per eventi come così:

import your.package.removeListenerWhenFired 

// ... class definition 

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

Questo è un bel trucco a cui non ho pensato, grazie! –

+0

nessun problema;) le chiusure sono davvero molto utili. Sto costruendo un sacco pieno di chiusure e trucchi di funzioni globali, vedendo dove andrà tutto. –

+0

Come rimuoveresti manualmente tale listener, poiché l'ascoltatore che stai aggiungendo è una funzione anonima? Se non riesci a rimuoverlo manualmente, prima o poi sarai su un bug. – chichilatte

2

I Non l'ho provato, ma potevi semplicemente trasformare il metodo statico EventUtil in un metodo standard ed estendere la classe nel tuo oggetto.

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

Non posso usare l'ereditarietà poiché AS3 non consente l'ereditarietà multipla e la maggior parte delle mie classi ne sta già estendendo un'altra. Ho pensato di inserire questa funzione in un file .as esterno che includerò in tutte le mie classi, ma mi stavo chiedendo se esistesse un modo migliore per farlo realmente. –

+0

Potrei anche aggiungere la funzione alla classe UIComponent direttamente nel Flex SDK; quello risolverebbe il mio problema, ma è ancora più brutto =/ –

1
functionadd.addEventListener(COMPLETE,functionremove); 

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