Comunidad de diseño web y desarrollo en internet online

interactuar entre clases

Citar            
MensajeEscrito el 23 Oct 2008 11:15 am
Hola, haber si me podeis echar una mano para comprender el funcionamiento entre clases.

Normalmente utilizo clases para ordenar el codigo. Pero cuando desde la clase del documento creo una instancia de otra clase:

...
var subir:subirArchivo = new subirArchivo();
...

dentro de la clase nueva (subirArchivo.as) a veces necesito acceder a componentes o Movieclips:



Código :

package {
   import flash.net.FileReference;
   import flash.net.FileReferenceList;
   import flash.errors.IllegalOperationError;
   import flash.net.URLLoader;
  ...

   public class subirArchivo{
      private var fileReference:FileReference;
      private var urlRequest:URLRequest;
     var amf:CallPHP = new CallPHP("http://localhost/amfphp/gateway.php");   
     private var sizeMax:Number; 
     private var errorTxt:TextField;
     
      public function subirArchivo():void {  openFileWindow();  }
      
      private function openFileWindow():void {
         urlRequest=new URLRequest();
        urlRequest.url="http://www.misitio.com/uploadFile.php";
       
         try {
            fileReference=new FileReference();
            fileReference.browse();
            fileReference.addEventListener(Event.SELECT, elegirArchivo); 
            fileReference.addEventListener(ProgressEvent.PROGRESS, precargaArchivo);  
         } catch (illegalOperation:IllegalOperationError) {
           
         }

      }
      private function elegirArchivo(e:Event):void {        fileReference.upload(urlRequest);        }     
     
      private function precargaArchivo(e:ProgressEvent):void {
         trace(e.bytesLoaded + " of " + e.bytesTotal + " bytes");
         estatusTxt.text = e.bytesLoaded;  //intento acceder a un texto dinamico de mi pelicula
      }
   }
}



Cuando intentamos acceder a estatusTxt en el metodo precargaArchivo obtengo e siguiente error:

TypeError: Error #1009: No se puede acceder a una propiedad o a un método de una referencia a un objeto nulo.

Por oscarlosan

73 de clabLevel



 

firefox
Citar            
MensajeEscrito el 23 Oct 2008 02:06 pm
El motivo del error es lo más sencillo de explicar: sencillamente lo que hace es buscar "estatusTxt" DENTRO de la Clase "subirArchivo".
Soluciones:
1.-La mala: pasar como argumento donde estamos a la hora de hacer el new. Así

Código ActionScript :

//en la clase documento
var subir:subirArchivo = new subirArchivo(this);


Código ActionScript :

//en tu subirArchivo.as
//añadimos la variable _stage
private var _stage:MovieClip;
//en la función subirArchivo
public function subirArchivo(obj:MovieClip):void {
   _stage=obj: //<--damos valor a la variable
   openFileWindow();
}
....
//usaremos
_stage.estatusTxt.text=e.bytesLoaded;


Vale, es una solución que a los más puristas de la OOP les va a dar cien patadas (con razón). En OOP se trata de que el valor de statusTxt sea cambiado SÓLO en la película principal.
Dicho de otro modo NUNCA vas a poder usar la clase "subirArchivo" en ningún proyecto tuyo ni nadia la va a poder usar (so pena que tenga una caja de texto que se llame statusTxt)
2.-La buena:Aunque algo más complicada, no te asustes, derivar la clase de Dispatch Event y crear un evento.


Código ActionScript :

publix class SubirArchivo=extends EventDispatcher { //<--la estendemos de eventDispatcher
public static var CHANGE:String = "Change"; //<--declaramos dos constante
public static var NO_EXISTE:String="No existe"

public var:_bytesTotal:Number=0;
public var:_bytesLoaded:Number=0;

public function SubirArchivo():void { openFileWindow(); }
.....
//tu función precargaArchivo mandará un evento
private function precargaArchivo(e:ProgressEvent):void {
   _bytesTotal=e.bytesTotal;
   _bytesLoaded=e.bytesLoaded
   dispatchEvent(new Event(SubirArchivo.CHANGE));
}
....


Vale, tu Clase Main debería quedar como

Código ActionScript :

main(){
   var subir:subirArchivo = new SubirArchivo();
   subir.addEventListener(SubirArchivo.CHANGE,mostrarProgreso);

   private function mostrarProgreso:void(e:Event){
      estatusTxt.Text=subir._bytesLoaded.toString() + " of " + subir._bytesTotal.toString() + " bytes"
   }
}


NOTA:He renombrado la Clase "subirArchivo" como "SubirArchivo", porque se acostumbra a que las Clases empiecen siempre por mayúsculas
NOTA2:He dejado como trabajo que, si no existe el archivo, dispache un evento del tipo SubirArchivo.NO_EXISTE

Vale, me vas a decir que es mucho rollo hacer las cosas bien. No te voy a contradecir en ese sentido. Sí te digo la ventaja que tiene esta segunda forma: esa clase ya la puedes "empaquetar" y la puedes usar en cualquier otro proyecto. Además, no me negarás que es mucho más parecida a, p.e. la clase Loader

Por Eliseo2

710 de clabLevel



 

firefox
Citar            
MensajeEscrito el 23 Oct 2008 02:47 pm
Sí, existen esas dos maneras, pero te aconsejo, como bien dicen, el dispatcher... Aunque es más complicado de entender (al principio) luego verás que vale la pena, pues no te complicas tanto la vida a la hora de meter más interacciones con otras clases que lo necesites...

Te aconsejaría que te leyeras este tip:
http://www.cristalab.com/tips/51078/comunicacion-entre-clases-actionscript-3-con-eventdispatcher.html
A mí me ayudó bastante

Un saludo ^^

Por Uruviel

48 de clabLevel



Genero:Femenino  

msie7
Citar            
MensajeEscrito el 24 Oct 2008 06:30 am
Mejor explicado imposible. Voy a modificar todas mis clases. Gracias.

Por oscarlosan

73 de clabLevel



 

firefox

 

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