2010-03-19 45 views
5

Estoy buscando una forma de agregar un EventListener que se eliminará automáticamente después de la primera vez que se dispare, pero no puedo encontrar la forma de hacerlo de la manera que quiero .AS3 - Escucha de eventos que solo se activa una vez

me encontré con esta función (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); 
    } 
} 


Pero en lugar de tener que escribir:

EventUtil.addOnceEventListener(dispatcher, eventType, listener); 

me gustaría usarlo de la forma habitual:

dispatcher.addOnceEventListener(eventType, listener); 


¿Alguien tiene una idea de cómo se podría hacer esto? ¿nordeste?
Cualquier ayuda sería muy apreciada.


(Sé que es Signals Robert Penner puede hacer esto, pero no puedo usarlos ya que significaría una gran cantidad de reescritura del código que no puedo pagar por mi proyecto actual)

+0

intente utilizar el [señales Biblioteca] (https://github.com/robertpenner/as3-signals/wiki). –

Respuesta

11

me parece la manera más limpia sin necesidad de utilizar la estática o echar a perder su código con el ruido es definir una función global (en un archivo llamado removeListenerWhenFired.as) de esta manera:

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

entonces se puede detectar eventos, así:

import your.package.removeListenerWhenFired 

// ... class definition 

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

¡Es un buen truco en el que no pensé, gracias! –

+0

no hay problema;) los cierres son realmente muy útiles. Estoy construyendo una bolsa llena de cierres y trucos de funciones globales, viendo dónde irá todo. –

+0

¿Cómo eliminaría manualmente dicho oyente, ya que el oyente que está agregando es una función anónima? Si no puedes eliminarlo manualmente, tarde o temprano serás culpable de un error. – chichilatte

2

I No lo he probado, pero podría convertir el método estático EventUtil en un método estándar y extender la clase en su objeto.

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

No puedo usar la herencia ya que AS3 no permite la herencia múltiple, y la mayoría de mis clases ya están extendiendo otra. Pensé en poner esta función en un archivo .as externo que incluiré en todas mis clases, pero me preguntaba si había una manera más agradable de hacerlo. –

+0

También podría agregar la función a la clase UIComponent directamente en el SDK de Flex; eso resolvería mi problema, pero es incluso más feo =/ –

1
functionadd.addEventListener(COMPLETE,functionremove); 

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