Comunidad de diseño web y desarrollo en internet online

Problemas con Datagrid [AS3-AIR-FLASH CS6]

Citar            
MensajeEscrito el 30 Abr 2013 10:17 pm
Hola, tengo varias clases creadas y estoy aprendiendo a utilizar dispatchEvent.
En principio dispatchEvent funciona bien, pero en una clase en concreto dispatchEvent funciona sin problemas en una parte de la clase, pero en otra parte no y no entiendo porqué.
Llevo todo el día probando cosas y no hay forma, no funciona y no entiendo el motivo.

Tengo las siguientes clases:

MAIN: clase principal, en su constructor creo las instancias de las otras clases y los addEventListener correspondientes para los eventos. Además en el MAIN tengo las funciones que se ejecutan al llegar las señales de los eventos.

NAVIGATIONEVENT: Clase muy sencilla que recibe la señal y la reenvía a la clase padre (en este caso el MAIN).

BARRADEESTADO: Clase muy sencilla, tiene un MC asociado con un campo de texto. Típica barra de estado de un programa.

VENTANALIBRO: Es la clase "problemática". Al ser instanciada desde el main, hace varias cosas y debería mandar una señal a BarraDeEstado con un texto que NO sale.
Además, tiene 2 funciones que se activan al pulsar un botón, estas funciones mandan cada una un dispatchEvent a BarraDeEstado y funcionan las dos perfectamente.
Tiene un MC asociado con campos de texto.


Aquí parte del MAIN (clase principal)

Código :

public class Main extends MovieClip 
{
public var miDatabaseManager:DatabaseManager;   
private var miBarraDeEstado:BarraDeEstado;
public var miVentanaLibro:VentanaLibro;
public var miListadoDeBuques:ListadoBuques;
   
   public function Main()
   {
   //crea una instancia de la barra de estado
   miBarraDeEstado = new BarraDeEstado();
   miBarraDeEstado.x = 0;      
   miBarraDeEstado.y = 900;      
   addChild( miBarraDeEstado );   
      
   //crea una instancia de VentanaLibro
   miVentanaLibro     = new VentanaLibro();   
   miVentanaLibro.x = 0;      
   miVentanaLibro.y = 0;   
   miVentanaLibro.addEventListener( NavigationEvent.MENSAJE,    escribe_un_mensaje );
   addChild( miVentanaLibro );   

   [..aqui sigue el constructor..]
   } //fin del constructor


   //evento para escribir mensajes en la Barra de Estado
   public function escribe_un_mensaje( e:NavigationEvent ):void
   {
      trace("aquí");
      miBarraDeEstado.actualizaBarraDeEstado(e.data);
   }   

[...aqui sigue el main con otras cosas...]

}



Clase BarradeEstado

Código :

package 
{
import flash.display.MovieClip;   
public class BarraDeEstado extends MovieClip 
{   
   public var mensaje;
      
   public function BarraDeEstado()
   {
      campoMensajes.text = "Barra de estado iniciada";
   }
      
   public function actualizaBarraDeEstado(sms:String)
   {
      campoMensajes.text = sms;
   }      
}
   
}






Clase NavigationEvent

Código :

package 
{
import flash.events.Event;
   
public class NavigationEvent extends Event 
{
   public static const MENSAJE:String      = "mensaje";
   public var data:String;
      
   public function NavigationEvent( type:String )
   {
      super( type );
   }
}
   
}




Y aquí la clase "problemática", tengo 3 dispatchEvents aquí y sólo funcionan 2.
Clase VentanaLibro

Código :

package 
{
[..aqui los imports..]
   
public class VentanaLibro extends MovieClip
{   
   //CONSTRUCTOR
   public function VentanaLibro()
   { 
      // Personalizacion de los campos de texto 
      [..código configurando unos campos de texto..]
         
      //BOTON TEMPORAL
      botonTemporal.addEventListener(MouseEvent.CLICK, salvar );
         
      // Este es el dispatchEvent que aparentemente no va!!!!
      var a:NavigationEvent = new NavigationEvent(NavigationEvent.MENSAJE);
      a.data = "¡Programa OK!";
      dispatchEvent( a ); 
   } //fin del CONSTRUCTOR
      

      
   //método en el que el dispatchEvent SI funciona
   public function salvar(e:MouseEvent):void
   {
      if(comprueba_campos_minimos())
      {
         [..codigo diverso..]
         //manda un MENSAJE con un texto a la instancia de BarraDeEstado
         var c:NavigationEvent = new NavigationEvent(NavigationEvent.MENSAJE);
         c.data = " datos OK";
         dispatchEvent( c );
      }
   }
      
      
   //Funcion que comprueba que existen los campos necesarios para salvar en BBDD
   //en esta funcion  el que el dispatchEvent TAMBIEN funciona
   function comprueba_campos_minimos():Boolean
   {
      if(...condiciones...) 
      return true;
      else
      {
      var err:NavigationEvent = new NavigationEvent(NavigationEvent.MENSAJE);
      err.data = "¡Error!";
      dispatchEvent( err );
      return false;
      }
   }   
         
}
}


Explicación del code:
La barra de estado, al instanciarse, escribe en el campo de texto del MC asociado: "Barra de estado iniciada".
Hasta aquí bien.

Luego, al instanciar miVentanaLibro el texto de la barra de estao debería cambiar a "¡Programa OK!", al recibir el evento, pero no cambia.
En el constructor de VentanaLibro

¿Por qué no funciona ese dispatchEvent?

Por daniel69

78 de clabLevel



 

chrome
Citar            
MensajeEscrito el 01 May 2013 06:07 am
BuenAS:

Casi seguro es porque distribuyes ese evento en el constructor de la clase. El código del constructor se ejecuta cuando instancias una clase; o sea , cuando haces:

miVentanaLibro = new VentanaLibro();

y AUN no se ha añadido el listener. No sé si me explico: ese evento no lo capturas ya que se distribuye antes de que haya un listener que lo haga.

En el constructor de VentanaLibro añade un listener al evento ADDED_TO_STAGE y en su función controladora distribuye el evento.

Un saludo.

Por Lukánicos

Claber

468 de clabLevel



Genero:Masculino  

chrome
Citar            
MensajeEscrito el 01 May 2013 09:51 am
No he entendido nada jajaja
¿Lo que quieres decir es que, cuando se ejecuta el constructor de VentanaLibro, el Listener aun lo ha hecho, y por eso el dispatchEvent no se dispara? Eso tiene sentido.
---
PD: Vale, acabo de ver un par de ejemplos en internet. Simplemente he añadido esto en el constructor de VentanaLibro

Código :

         
addEventListener(Event.ADDED_TO_STAGE, init);

Y esto a parte:

Código :

      
private function init(e:Event):void
{
   var evMovil:NavigationEvent = new NavigationEvent(NavigationEvent.MENSAJE);   
   evMovil.data = "¡Programa OK!";
   dispatchEvent( evMovil );   
}



Ahora ya funciona. Lo que hace es redirigir la señal al MAIN por lo de ADDED_TO_STAGE??
Gracias por la ayuda Lukánicos



PD: ¿Ha cambiado el moderador el título del post? Porque no tiene nada que ver con Datagrids, ¡creo que se le ha ido la mano!

Por daniel69

78 de clabLevel



 

chrome
Citar            
MensajeEscrito el 01 May 2013 10:59 am
BuenAS:

En AS3 los eventos dependen de la displaylist, o sea, de la lista de visualización, que dicho en cristiano: un objeto para distribuir eventos (el que distribuye el evento, con dispatchEvent) tiene que añadirse al escenario (o a otro objeto que esté en el escenario). Y para escuchar un evento el objeto (al que le añades el addEventListener) también tiene que estar en el escenario (o en otro objeto que esté en el escenario) y jerárquicamente hablando, ser su ascendente.

Por tanto, cuando trabajas con eventos tienes que asegurarte de varias cosas:

1. Que el que distribuye el evento (dispatchEvent) está en la lista de visualización, de ahí esperar a que se produzca el evento ADDED_TO_STAGE (que significa "añadido al escenario"). Si emites un evento antes de que ocurra esto, se va a perder.

2. Que el que capture el evento (addEventListener) esté jerárquicamente por encima del que lo emite (este no es tu problema); o sea que el que lo emite sea hijo, nieto, etc. del que lo captura.

3. A este punto no le hagas mucho caso, ya que es útil cuando tienes una jerarquía de objetos anidados compleja y quieres escuchar eventos de objetos anidado. Si el que lo captura no está un nivel por encima del que lo emite, asegurarte de que el evento "burbujea". Cuando creas un evento, el segundo parámetro que se le pasa es la propiedad bubbles, que por defecto es false. Y al addEventListener, el tercer parámetro es useCapture, que por defecto es false, y habría que pasarle true.

Esta locura de que los eventos en AS3 dependan de la lista de visualización (Display List) puede evitarse recurriendo a Signals. Es otra filosofía totalmente distinta: creas un Signal, se lo pasas al objeto del que quieres recibir información que distribuirá mensajes con el método dispatch, y los objetos que quieren recibir los mensajes le añaden listeners.

Signals no depende de la lista de visualización, por lo que cualquier objeto puede distribuir mensajes a cualquier otro en cualquier momento.

Un saludo.

Por Lukánicos

Claber

468 de clabLevel



Genero:Masculino  

chrome

 

Cristalab BabyBlue v4 + V4 © 2011 Cristalab
Powered by ClabEngines v4, HTML5, love and ponies.