Comunidad de diseño web y desarrollo en internet online

Problema al eliminar elementos de la lista de visualización

Citar            
MensajeEscrito el 20 May 2010 11:45 am
Hola, tengo un problema que es casi más complicado de explicar q la dificultad de codificarlo.
El problema me viene a la hora de eliminar/ocultar elementos de lista de visualización de la aplicación
cuando pasamos de un frame a otro. Voy a tratar de explicarme lo mejor posible, aunque aviso es algo denso....

1. //En el Frame1 de mi linea de tiempo general.

Código ActionScript :

var pantalla1:clasePantalla1=new clasePantalla1();
addChild(clasePantalla1);


-Muestro un tipo de pantalla que se 'construye' mediante una única clase (ayudada de otras clases hijas). A esta clase la llamaremos p.e. clasePantalla1.

Esta clase se forma a partir de dos clases que llamaremos claseComponenteTipo1+claseComponenteTipo2. Por tanto:
la clasePantalla1=claseComponenteTipo1+claseComponenteTipo2.

-La claseComponenteTipo1 es una barra de navegación generada dinámicamente a partir del contenido de un archivo XML (pero eso ahora no es importante).
Esta clase entre otras cosas detecta el evento del [CLICK] del mouse sobre sus botones (en realidad son Mc) y se lo comunica a la clase 'padre' mediante
la creación y propagación de eventos (dispatcher). En esto no me entretengo porque la detección y propagación de eventos funciona correctamente.
Proceso:
-claseComponenteTipo1 detecta [CLICK] sobre un botón y crea un nuevo evento que se propaga a la clase clasePantalla1.
-clasePantalla recibe el evento procedente de claseComponenteTipo1
-y mediante una función registrada para la detección del evento, detiene la propagación del mismo puesto que ya se ha recibido

Código ActionScript :

...
              dispatcher = ClassDispatcher.getInstancia();
               dispatcher.addEventListener(ClassDispatcher.TERMBAR_CLICK,DetectEvent);      
            ...
            
            private function DetectEvent(e:Event){
            
               trace("Detecto el evento de la clase TermBar desde la clase TermScreen"); 
      
               //1.Ocultamos elementos de la pantalla actual
               RemoveAllComponents(); 
               ...
               //3. Ya hemos detectado el evento, detenemos la propagación
               e.stopImmediatePropagation();
               ...
               //4. Cambiar de pantalla/frame
               MovieClip(parent).gotoAndStop("pantallaN4_seccionTeoria");          
   
            }
         

-Elimina todos los comonentes previamente añadidos (en la linea de tiempo al iniciarse).

Código ActionScript :

...
               public function RemoveAllComponents():void{
         
                  //1. Eliminar la barra de componenentes compartidos
                  if(sharedComponents!=null){
                     removeChild(sharedComponents); 
                  }
                  //2. Eliminamos la barra de navegacion
                  if(termBar!=null){
                     removeChild(termBar); 
                  }
                  //3. Eliminamos el contenedor de SWF
                  if(loader!=null){         
                     removeChild(loader);          
                  }
                  
               }
         
...
-Cambia de frame (frame2)

Hasta aquí todo bien...Pasamos al frame 2
2.//Frame 2 de la línea de tiempo

Código ActionScript :

//0.1 Declaración de clases necesarias para componer la pantalla actual. 
var myInterface:Interface;
var indexContent:IndexContent; 
//1. Iniciamos componentes de la pantalla (frame)->Interfaz+Contenido
   //1.1. Interfaz global
   myInterface=new Interface(); 
   addChild(myInterface);
   //1.2. Contenidos 
   indexContent=new IndexContent();
   addChild(indexContent);   


En este frame el contenido por pantalla lo mostraremos a partir de dos clases. Por tanto:
Pantalla2 (que NO clase)= claseInterface+claseContenido

-El funcionamiento de la claseInterfaz es confuso de explicar porque hay varios componentes q hacen diferentes
cosas según convenga pero me centraré en que hay un control que nos hace volver al frame anterior (frame1).

-Por otro lado la claseContenido muestra un contenido dinámico u otro dependiendo de la entrada indicada por el usuario en el
frame anterior (ésto tampoco es relevante ahora).

Proceso:
-claseInterfaz detecta evento [CLICK] sobre uno de sus controles

Código ActionScript :

         componente.addEventListener(MouseEvent.CLICK, ThrowEvent);
      

-función detectora de evento [CLICK] dentro de la misma clase, entre otras cosas creará un evento que propagará a la claseContenidos.

Código ActionScript :

            private function ThrowEvent(e:MouseEvent):void
            {
               ....
               
               dispatcher = ClassDispatcher.getInstancia();
               dispatcher.dispatchEvent(new Event(ClassDispatcher.HIDE_CONTENT));                  
                  
               ...
               
            }
      

-En la claseContenidos tenemos un dispatcher para la escucha del evento externo q lo capta y actua al respecto mediante otra función detectora

Código ActionScript :

            dispatcher = ClassDispatcher.getInstancia();
               dispatcher.addEventListener(ClassDispatcher.HIDE_CONTENT,DetectEvent);
      


- Elimina todos los componentes previamente añadidos

Código ActionScript :

         private function RemoveComponents():void{
         
            if(temasArray!=null){
               for(var i:uint; i<temasArray.length;i++){
                  removeChild(temasArray[i])
               }
            }
         }//end 'RemoveComponents()
      

- Volvemos al frame anterior.

Explico donde viene el problema, voy del frame 1 al frame 2-> OK, vuelvo del frame 2 al frame1 -> OK, vuelvo de nuevo del frame 1 al frame 2->ERROR!!!
"ArgumentError: Error #2025: El objeto DisplayObject proporcionado debe ser un elemento secundario del llamador.
at flash.display::DisplayObjectContainer/removeChild()
at myAs::TermScreen/RemoveAllComponents()"
El error se produce en la clase del frame 1 (clasePantalla1) al eliminar los componenentes. Sé que este tipo de error sucede cuando tratamos de eliminar
un componente q ya ha sido eliminado o no está en la lista de visualización...pero no acabo de ver como remediarlo. De hecho los compnentes desaparecen y
me deja continuar pero posteriormente enb otras clases q no he indicado y que mantienen este funcionamiento me surge el error y sin embargo el contenido
no desaparece superponiedose al contenido anterior...

He reducido el código al máximo para evitar mayor aburrimiento del q ya habré provocado :S. Otro aspecto sé q es el de incluir código en la linea de tiempo,
he intendado evitarlo al máximo, no obstante también estoy trabajando en ello para que no aparezca nada.
Qué más... sé q a veces cuando trabajamos con varios frames el código se ejecuta antes de q los elementos gráficos estén disponibles...No obstante, en mi caso
creo q es el caso inverso porque avanzamos 1 frame pero eliminamos lo del frame posterior q ya ha sido mostrado....
Sé que es algo pesado lo que comento pero necesito solucionarlo porque algo tan tonto se arrastra continuamenente. Agradezco mucho a quien tenga la paciencia de
leer hasta el final :S

un saludo!

Por emedmaria

73 de clabLevel



 

firefox
Citar            
MensajeEscrito el 21 May 2010 10:36 am
Supongo que el problema lo tienes porque para eliminar usas un Array

Código ActionScript :

for(var i:uint; i<temasArray.length;i++){ 
       removeChild(temasArray[i]) 
}

y ese "array" no lo actualizas (No veo, por ningún lado ningún temasArray.slice o temasArray.pop)

Aparte de ese problema -que deberías tener "coordinado" el array con los elementos de la DisplayList -si no, al final vas a tener problemas- comento dos opciones
1.-Usar el método "contains" (es un método de la Clase DisplayObjectContainer de la que extienden todos los Sprites y el Stage)

Código ActionScript :

for(var i:uint; i<temasArray.length;i++){ 
       if (contains(temasArray[i]){
            removeChild(temasArray[i]) 
       }
}

2.-Olvidar el array y usar getChildAt o getChildByName para referirte a los elementos que hay DENTRO de un DisplayObject determinado.

Código ActionScript :

//Si queremos eliminar todos los objetos que estén DENTRO de un MC "mimc"
while (mimc.numChildren){
    removeChildAt(0)
}
//Si es en una clase
while (mimc.numChildren){
    removeChildAt(0)
}

Código ActionScript :

//Si queremos mover a la derecha todos los objetos que estén DENTRO de un MC "mimc"
for (var i=0;i<mimc.numChildren;i++){
       mimc.getChildAt(i).x+=10
}
//Si es en una clase
for (var i=0;i<numChildren;i++){
       getChildAt(i).x+=10
}

Habrá veces que precises hacer una "conversión de cast"

Código ActionScript :

//Si los objetos  DENTRO de un MC pertenecen a la clase "MiClase" y queremos ejecutar un método
for (var i=0;i<mimc.numChildren;i++){
       var mc_especial:MiClase=mimc.getChildAt(i) as MiClase
       mc_especial.metodo1()
}
//Si es en una clase
for (var i=0;i<numChildren;i++){
       var mc_especial:MiClase=getChildAt(i) as MiClase
       mc_especial.metodo1()
}

Por Eliseo2

710 de clabLevel



 

firefox
Citar            
MensajeEscrito el 21 May 2010 11:27 am
Eliseo, mil gracias de nuevo :)

Voy a probar lo que me comentas. Agradezco mucho tu paciencia :)

Por emedmaria

73 de clabLevel



 

firefox

 

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