Comunidad de diseño web y desarrollo en internet online

new XML(event.target.data) Uso de eventos.

Citar            
MensajeEscrito el 03 Mar 2009 08:08 pm
Hola, trabajo con Flex y el Api de GMAPS, y los datos estan en una BD sql, con 2 tablas, markers (marcas en el mapa de GoogleMaps) y fotos (imagenes asociadas a cada marca)


Cada vez que creo una marca nueva, (q obtengo desde un xml generado a partir de la BD sql), creo asociado a la marca un InfoWindowTabbedComponent, que es donde visualizaré las fotos asociadas a cada marca (y almacenadas en la tabla fotos en la Bd sql).

El código es el siguiente:

Código :


public function createMarker(id:int, latlng:LatLng, nombre:String, descripcion:String, tipo:String, zoom:int):void {
          var markerOptions:MarkerOptions = new MarkerOptions({});        
         var marker:Marker = new Marker(latlng, markerOptions);  
         var options:InfoWindowOptions = new InfoWindowOptions({
                customContent: new InfoWindowTabbedComponent(marker,id),
                 });
}



Y la clase InfoWindowTabbedComponent modificada:

Código :


public class InfoWindowTabbedComponent extends UIComponent {
              
 
  public var marker:Marker;
  public var id_marca:int;
  public var nombre_foto:String;
  
  public function InfoWindowTabbedComponent(m:Marker,id_m:int) {
      marker = m;
      id_marca=id_m;
      getData();
     var panel:Box = new Box();
      panel.width = 290;
      panel.height = 100;
      
      var hbox:HBox = new HBox();
      var labelName1:Label = new Label();
      labelName1.text = String(id_marca);
      labelName1.width = 70;
      
      var labelName2:Label = new Label();
      labelName2.text = String(nombre_foto);
      labelName2.width = 70;
}
  public function getData():void {
    
    var urlRequest:URLRequest = new URLRequest("phpSqlToXml_fotos.php");  
    urlRequest.method = URLRequestMethod.POST;    
    var variables:URLVariables = new URLVariables(); 
    variables.id_marca = id_marca;
    urlRequest.data = variables; 
    var urlLoader:URLLoader = new URLLoader(urlRequest); 
    urlLoader.addEventListener(Event.COMPLETE,readXml)
}                                       

public function readXml(event:Event):void{          
       var fotosXML:XML = new XML(event.target.data);
        var fotos:XMLList = fotosXML.foto;
        var fotosCount:int = fotos.length();               
           for (var i:Number = 0; i < fotosCount; i++) {
               var foto:XML = fotos[i];
               var id_foto:int = foto.@id; //Con el id seleccionamos de la marca luego buscamos las fotos y videos
               var nombre:String = foto.@nombre;
               nombre_foto=nombre;
               var descripcion:String = foto.@descripcion;          
           }
       }

Lo que quiero es poder ejecutar readXML(event:Event) a continuación de getData(), como si fuesen una única función para que no se quede esperando con urlLoader.addEventListener(Event.COMPLETE,readXml), sino que justo después de
var urlLoader:URLLoader = new URLLoader(urlRequest); ya pueda obtener los datos del XML con
var fotosXML:XML = new XML(event.target.data); sin necesidad del event.COMPLETE.
El problema está en ese event.target.data que le paso a la funciónn y a partir del cual creo el XML que no lo puedo omitir y tampoco sé si se puede escribir de otra forma sin usar un event.
Espero haberme explicado y que se entienda. Soluciones?
Gracias.

Por riestra

73 de clabLevel



 

msie7
Citar            
MensajeEscrito el 04 Mar 2009 07:37 am

riestra escribió:


Lo que quiero es poder ejecutar readXML(event:Event) a continuación de getData(), como si fuesen una única función para que no se quede esperando con urlLoader.addEventListener(Event.COMPLETE,readXml), sino que justo después de
var urlLoader:URLLoader = new URLLoader(urlRequest); ya pueda obtener los datos del XML con
var fotosXML:XML = new XML(event.target.data); sin necesidad del event.COMPLETE.

NO se puede, para rellenar las fotos debes saber con qué. Puedes poder un mensaje de "loadding" al principio de tu función getData y, en el Event.COMPLETE eliminar dicho mensaje, o que la última instrucción del contructor de la Clase "InfoWindowTabbedComponent" sea ese "getData()". sinceramente no le veo "la vuelta" a lo que quieres hacer :(

Por Eliseo2

710 de clabLevel



 

firefox
Citar            
MensajeEscrito el 04 Mar 2009 10:14 am
Creo que me he explicado algo mal, así que lo pongo más simplificado:

Cada vez que creo un objetoc, creo un infowindotabbedcomponent, y cada vez que creo este infow... en su código llamo a la función getData, que a su vez llama a readXML cuando even.COMPLETE==true;

Código :

public function InfoWindowTabbedComponent(m:Marker,id_m:int) {
    
   //  Codigo
          
    getData();
    
   //  Más código
   
}

public function getData():void {
    //Código
     urlLoader.addEventListener("complete",readXml);
}

public function readXml(event:Event):void{
        var fotosXML:XML = new XML(event.target.data);
        //Código;
}



Bien, tal y como está cuando yo creo 4 objetos Infow, se crea el InfoWindow...1, se ejecuta getData(), y NO se lanza todavía readXML, sino que queda a la espera, luego viene el InfoWindow...2, se ejecuta getData para este segundo objeto, y NO se lanza todavía readXML para este InfoWindow...2, tambien queda a la espera, y así sucesivamente hsata que se creen todos los objetos y al final es cuando se lanza readXML para el InfoWind...1, readXML para el InfoWind....2, etc.

Yo necesito que los readXML NO se lancen juntos al final, sino que cuando se cree el InfoWind...1, y ejecute getData a continuación ya se lance readXML para ese InfoWind...1, ya luego creamos InfoWind....2, se ejecuta getData para InfoWindow....2, y lanzamos readXml para InfoWind....2

¿Cómo lo hago???? Espero que ahora haya quedado más claro y fácil de entender el problema.

Por riestra

73 de clabLevel



 

msie7
Citar            
MensajeEscrito el 04 Mar 2009 02:24 pm
Creo haberlo entendido :)
Realmente, tal y como está lo que hace es crear el InfoWindow1 y mandar a cargar, se crea el InfoWindow2 y manda a cargar...
Sólo cuando ha cargado el dato, se hace el readXML correspondiente
Si lo que queremos es crear el InfoWindow1, mandar a cargar, una vez que se ha cargado hacer el readXML y crear el InfoWindow2, mandar a cargar.... NO podemos hacer

Código ActionScript :

//NO podemos hacer
createMarker(0, latlng, nombre);
createMarker(1, latlng, nombre);
createMarker(2, latlng, nombre);
createMarker(3, latlng, nombre);

Yo lo haría "dispachando eventos". Vamos, cuando InfoWindowTabbedComponent haya acabado de leer "dispache un evento".
Como debemos añadir un listener para que ese evento pueda ser escuchado, quitaremos el getData de la función constructora y lo dejaremos como un simple método.

Código ActionScript :

public class InfoWindowTabbedComponent extends UIComponent {
  public var marker:Marker;
  public var id_marca:int;
  public var nombre_foto:String;
  
  //como haremos uso de labelName2 en la función readXml, la declaramos aquí
  var labelName2:Label

  public function InfoWindowTabbedComponent(m:Marker,id_m:int) {
      marker = m;
      id_marca=id_m;
      var panel:Box = new Box();
      panel.width = 290;
      panel.height = 100;
      
      var hbox:HBox = new HBox();
      var labelName1:Label = new Label();
      labelName1.text = String(id_marca);
      labelName1.width = 70;
     
      //aquí creamos la label
      labelName2= new Label();
      //pero no escribimos labelName2.text = String(nombre_foto);
      labelName2.width = 70;
 
      //en NINGÚN momento llamamos a getData()
}

public function getData():void {
    //Código
     urlLoader.addEventListener("complete",readXml);
}

public function readXml(event:Event):void{
        var fotosXML:XML = new XML(event.target.data);
        var fotos:XMLList = fotosXML.foto;
        var fotosCount:int = fotos.length();               
           for (var i:Number = 0; i < fotosCount; i++) {
               var foto:XML = fotos[i];
               var id_foto:int = foto.@id; //Con el id seleccionamos de la marca luego buscamos las fotos y videos
               var nombre:String = foto.@nombre;
               nombre_foto=nombre;
               var descripcion:String = foto.@descripcion;          
           }
         //al final del código le damos valor a la labelName2
         labelName2.text = String(nombre_foto);
        //Y aquí "dispachamos" un evento
        dispatchEvent(new Event("completeReadXML"));
}


Nuestra función CreateMarker sería

Código ActionScript :

public function createMarker(id:int, latlng:LatLng, nombre:String, descripcion:String, tipo:String, zoom:int):void {
          var markerOptions:MarkerOptions = new MarkerOptions({});        
         var marker:Marker = new Marker(latlng, markerOptions); 
         var customContent:InforWindowTabbedComponent=new InfoWindowTabbedComponent(marker,id);
         customContent.addEventListener("completeReadXML",crearOpciones);
          customContent.getData();  //<---le decimos que lea la data
}
public function crearOpciones(e:Event):void{
         var options:InfoWindowOptions = new InfoWindowOptions({
                customContent: e.target});
         e.target.removeEventListener("completeReadXML",crearOpciones)
         //y aquí dispatchamos otro evento de que se ha creado la marca
        dispatchEvent(new Event("completeCrearOpciones"));

}

La función Main, podríamos escuchar el evento completeCrearOpciones y llamar a cargar

Código ActionScript :

package{
   public class Main extends MovieClip{
   private num_id:Number=10;
   private num_id_actual:Number=0;
   
   public function Main(){
       addEventListener("completeCrearOpciones",nuevaOpcion);
       CreateMarker(num_id_actual,latlng,nombre,descripcion,tipo,zoom);
   }
   public function nuevaOpcion(){
       num_id++;
       if (num_id_actual<num_id){
            CreateMarker(num_id_actual,latlng,nombre,descripcion,tipo,zoom);
       }else{
            removeEventListener("completeCrearOpciones",nuevaOpcion);
       }
   }
}


No sé si es eso lo que quieres o lo he liado todo (últimamente ando trope de entendederas)

Por Eliseo2

710 de clabLevel



 

firefox
Citar            
MensajeEscrito el 04 Mar 2009 04:36 pm
Bueno, antes de nada gracias por responder.
Me parece una solución, pero no se si es la mejor solución dispachar tanto evento. También porque tendría que modificar muchas cosas, entre ellas el main, que preferiría no tocarlo la verdad......

¿No hay como meter esas 3 líneas en la misma función cambiando el argumento event de entraada del new XML() por algun otro argumento, y que no tenga que quedarse escuchado si el evento es complete?
.
.
.
var urlLoader:URLLoader = new URLLoader(urlRequest);
urlLoader.addEventListener("complete",readXml);
}
public function readXml(event:Event):void{
var fotosXML:XML = new XML(event.target.data);



Gracias, un saludo.

Por riestra

73 de clabLevel



 

msie7
Citar            
MensajeEscrito el 04 Mar 2009 05:05 pm
Supongo que puedes leerte todos los datos XML de una vez y pasarle a la función createMarker dicho XML, así te evitarías leerlos de uno en uno (en lugar de las llamadas que sean al servidor, sólo realizas una)

Por Eliseo2

710 de clabLevel



 

firefox
Citar            
MensajeEscrito el 06 Mar 2009 01:22 pm
Bueno gracias por las respuestas, después de probar con lo que me dijisteis y darle vueltas y más vueltas, la solución era mucho más facil de lo que parecía:

El getXMLfotos() en el principal que dentro llamaba a readXMLfotos(event) mediante el addEventListener, dentro de readXMLfotos cada foto leida la paso a un array global llamado todas_las_imagenes,donde almaceno las imagenes de mi BD y cuando ha leido todas lanzo getXMLmarkers() que de nuevo mediante addEventListener llama a readXMLmarkers(event), mediante el id de cada marca comparando con el id_marca que contiene cada imagen del array todas_as_imagenes obtengo un array con las imagenes pertenecientes a una marca determinada. imagenes_marca_actual:Array

A continuación creo la marca con Createmarker(argumentos) pasandole este imagenes_marca_actual como un argumento, que a su vez sera pasado al InfoWindowTabbedComponent que se crea mientras se está creando la marca y listo, ya tengo en el InfoWindow las imágenes de la BD asociadas a la marca.

Ahora solamente me falta encontrar el componente adecuado de Flex que me permita mostrar esas imágenes de manera correcta, en forma de image gallery o algo parecido, pudiendo añadir un eventListener por si el usuario hace un Click y ampliar la imagen seleccionada.
¿Alguna sugerencia?

Por riestra

73 de clabLevel



 

msie7

 

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