Home » AS3 »Avanzado »Class » Currently Reading:

Comunicación entre clases Actionscript 3 con EventDispatcher

enero 15, 2008 AS3, Avanzado, Class 6 Comments
Comunicación entre clases Actionscript 3 con EventDispatcher

A raíz de una pregunta en un post anterior explicaré cómo detectar eventos personalizados entre clases de Actionscript 3. Para poder, por ejemplo, que una clase pueda detectar cuando otra clase a ejecutado una acción en concreto o ha completado una carga de datos externa.

La interfaz IEventDispatcher define métodos para añadir o quitar detectores de eventos. Son muchas las clases que implementan esta interfaz y por lo tanto permiten lanzar y escuchar eventos, cómo lo es la clase DisplayObject con lo que en cualquier clip podremos añadirle un detector de “escuche” (por ejemplo) el evento que lanza automáticamente la clase MouseEvent cada vez que hacemos click sobre él:

  1. clip.addEventListener(MouseEvent.CLICK, detectaEvento);
  2.  
  3. function detectaEvento(e:MouseEvent):void
  4. {
  5.     trace("Detecto el mouse click");
  6. }

Ahora bien, conel método dispatchEvent() podemos lanzar nuestros propios eventos desde nuestras clases. ünicamente crearemos un evento con el nombre que queramos.

  1. dispatchEvent(new Event("onClick"));

y para detectar:

  1. addEventListener("onClick",detectaEvento);

Para hacerlo de una manera un poco más elegante podríamos crear una constante estática que guarde el nombre del evento. De esta manera una clase de ejemplo sería asi:

  1. package
  2. {
  3.     import flash.display.Sprite;
  4.     import flash.events.EventDispatcher;
  5.     import flash.events.Event;
  6.     import flash.events.MouseEvent;
  7.     //
  8.     public class ClaseA extends Sprite
  9.     {
  10.         public static  const CLICK:String = "onClick";
  11.         //
  12.         public function ClaseA()
  13.         {
  14.             var clip:Sprite = new Sprite();
  15.             clip.graphics.beginFill(0x000000);
  16.             clip.graphics.drawRect(0, 0, 50, 50);
  17.             clip.graphics.endFill();
  18.             addChild(clip);
  19.             addEventListener(MouseEvent.CLICK, lanzaEvento);
  20.             addEventListener(ClaseA.CLICK, detectaEvento);
  21.         }
  22.         private function lanzaEvento(e:MouseEvent):void
  23.         {
  24.             trace("Detecto el mouse click");
  25.             dispatchEvent(new Event(ClaseA.CLICK));
  26.         }
  27.         private function detectaEvento(e:Event):void
  28.         {
  29.             trace("Detecto el ClaseA click");
  30.         }
  31.     }
  32. }

Esta clase crear un gráfico que detecta el click del mouse, y a su vez lanza y detecta su propio evento.

Lo interesante es poder detectar estos eventos desde fuera de la clase. Por ejemplo, crearemos otra clase que detecte este evento lanzado por la ClaseA:

  1. package
  2. {
  3.     import flash.display.Sprite;
  4.     import flash.events.Event;
  5.     //
  6.     public class ClaseB extends Sprite
  7.     {
  8.         private var claseA:ClaseA;
  9.         //
  10.         public function ClaseB()
  11.         {
  12.             claseA = new ClaseA();
  13.             claseA.addEventListener(ClaseA.CLICK,detectaEvento);
  14.             addChild(claseA);
  15.         }
  16.         private function detectaEvento(e:Event):void
  17.         {
  18.             trace("Detecto el ClaseA click");
  19.         }
  20.     }
  21. }

Cómo vemos, para poder detectar el evento de una clase hemos de asignarle el addEventListener a su instancia. Es decir, este listener en la claseB no funcionaría:

  1. claseA = new ClaseA();
  2. addChild(claseA);
  3. addEventListener(ClaseA.CLICK,detectaEvento);

Entonces ¿cómo detectaremos eventos de clases que no están incluidas en las clases detectoras?
Tendremos que hechar mano de una clase intermedia (dispatcher) que sea la que realmente lance el evento:

  1. package
  2. {
  3.     import flash.events.EventDispatcher;
  4.     //
  5.     public class ClaseDispatcher extends EventDispatcher
  6.     {
  7.         private static var _instancia:ClaseDispatcher;
  8.         public static  const CLASEA_CLICK:String = "onClick_en_claseA";
  9.         //
  10.         public function ClaseDispatcher(s:Singleton)
  11.         {
  12.         }
  13.         public static function getInstancia():ClaseDispatcher
  14.         {
  15.             if (_instancia == null) {
  16.                 ClaseDispatcher._instancia = new ClaseDispatcher(new Singleton);
  17.             }
  18.             return _instancia;
  19.         }
  20.     }
  21. }
  22. class Singleton
  23. {
  24. }

Esta clase está escrita siguiendo el patrón Singleton para que solo se pueda crear una única instancia y esta sea accesible dese cualquier clase (ya escribiré un tip haciendo una explicación más extensa sobre este patrón ;)) .

De manera incluiremos esta clase dispatcher dentro de las clases que queramos mantener comunicadas:

  1. package
  2. {
  3.     import flash.display.Sprite;
  4.     import flash.events.EventDispatcher;
  5.     import flash.events.Event;
  6.     import flash.events.MouseEvent;
  7.     //
  8.     public class ClaseA extends Sprite
  9.     {
  10.         private var dispatcher:ClaseDispatcher;
  11.         //
  12.         public function ClaseA()
  13.         {
  14.             var clip:Sprite = new Sprite();
  15.             clip.graphics.beginFill(0x000000);
  16.             clip.graphics.drawRect(0, 0, 50, 50);
  17.             clip.graphics.endFill();
  18.             addChild(clip);
  19.             addEventListener(MouseEvent.CLICK, lanzaEvento);
  20.         }
  21.         private function lanzaEvento(e:MouseEvent):void
  22.         {
  23.             dispatcher = ClaseDispatcher.getInstancia();
  24.             dispatcher.dispatchEvent(new Event(ClaseDispatcher.CLASEA_CLICK));
  25.         }
  26.     }
  27. }
  1. package
  2. {
  3.     import flash.display.Sprite;
  4.     import flash.events.Event;
  5.     //
  6.     public class ClaseB extends Sprite
  7.     {
  8.         private var dispatcher:ClaseDispatcher;
  9.         //
  10.         public function ClaseB()
  11.         {
  12.             dispatcher = ClaseDispatcher.getInstancia();
  13.             dispatcher.addEventListener(ClaseDispatcher.CLASEA_CLICK,detectaEvento);
  14.         }
  15.         private function detectaEvento(e:Event):void
  16.         {
  17.             trace("Detecto el ClaseA click");
  18.         }
  19.     }
  20. }

Compártelo:

Comunicación entre clases Actionscript 3 con EventDispatcher
Visto 14.593 veces

Currently there are "6 comments" on this Article:

  1. andres dice:

    Hola… creo que si especificas en el contructor del evento que realice la face de captura, lo vas a poder capturar…

    Otra forma de hacerlo es usando un patron adapter bien sencillo, o simplemente definir la funcion adEventListener en claseB q solo haga la asignacion del evento a la instancia de claseA

    Saludos!

  2. luis dice:

    a mi no me funciona.
    me da error 1061:dice que la funcion dispatchevent no esta definida y eso que mi clase extiende EventDispatcher

  3. luis dice:

    perdon, era un fallo tonto… funciona guai
    gracias

  4. oscar dice:

    Hola… pues a mi no me funciona la claseB no detecta el evento. Lo he copiado exactamente como esta en el tutorial.:(

  5. oscar dice:

    ahora si me funciona :) pero… he creado una nueva clase test.as donde instancio claseA y claseB (¿es necesario instanciar claseB) y entonces si que me ha capturado el evento claseB. la comunicacion entre clases me cuesta un poquito de entenderla..

  6. Mlo dice:

    podrias ponerlo para descargar el ejemplo, esta de p.m. pero me queda grande… te felicito chaval, eres la ostia, te envidio (sanamente)…

Comment on this Article:








Twitter: zguillez

AdvertisementAdvertisementAdvertisementAdvertisement

Recibe las novedades por email



Map

Ranking

Codigoactionscript.org: 4.65 sobre 5 (106 valoraciones)

twitter-widget.com