Comunidad de diseño web y desarrollo en internet online

Llamar a un metodo del root desde un clip cargado con Loader

Citar            
MensajeEscrito el 03 Abr 2008 12:24 am
Esta es diferente a las preguntas del tipo "no se porque _root no funciona! :cry: ". Yo se xq _root no funciona y me parece bien, ya lo acepte :lol: .

Describo el caso ahora:
Tengo dos archivos copilados swf. padre.swf e hijo.swf. Padre.swf va a cargar a hijo.swf usando la clase Loader. El problema es que hijo.swf necesita ejecutar métodos que se encuentran en padre. La idea es no usar LocalConnection, busco una manera mas limpia.

Dado que en AS3 el root de cada clip es si mismo, no puedo subir hasta la raiz. En estos momentos extraño los métodos globales. Crear una clase con un método estático no sirve en este caso, xq para el clip hijo.swf la clase q contiene ese método no estará cargada y ocurrirá un error en la copilación de hijo.swf (cosa q se puede corregir con root["functionglobal"]() pero no es muy bonito. Aun asi, queda el problema de que root no sale de hijo.swf.

Puede que usando ApplicationDomain pueda lograrlo, pero por lo que he leído ninguna de las tres opciones que el me propone me sirve: Dominio separado, mesclar dominios, o reemplazar dominios.

No quiero que los dominios se mezclen. Lo que quiero lograr es cargar aplicaciones en ventanas y que estas ventanas usen ciertos métodos globales.

Todo esto ya lo tengo en AS2 - AS1. Pero deseo pasarlo a AS3 por las ventajas en la velocidad.

Ideas? ^^

Por dzegarra

14 de clabLevel



Genero:Masculino  

Lima, Peru

firefox
Citar            
MensajeEscrito el 03 Abr 2008 11:19 pm
Yo para ese tipo de cosas uso un singleton, donde guardo la referencia del root y no tengo que preocuparme por el scope de donde este, aparte de las ventajas que de el mismo.

Saludos!!!

Por Cep

BOFH

1509 de clabLevel

9 tutoriales

1 ejemplo

Genero:Masculino   REC Bastard Operators From Hell

Web Developer

firefox
Citar            
MensajeEscrito el 04 Abr 2008 01:42 pm
que ganas de complicarce la vida al pedo viejo!!
la verdad que yo no entiendo como hay gente que para un simple stop() hace una clase :roll:
yo creo que tu problema se coluciona poniendo el target en una variable, yo lo hago asi y funciona perfecto.

ejemplo:
cuando vos tenes un swf principal (root) y luego cargas un swf externo
con loader. vas a tener el loader mas el swf exerno. osea un (parent.parent)
pero la cosa se simplifica si queres llamar directamente al root. (y no hace falta hacer una clase para todo esto ni para muchas cosas... )

simplemente cuando cargas un swf externo le pasas como valor un listener o una referencia.
como se hace??.
si vos tenes todo el codigo en el (root) podes llamar a una funcion desde el loader de esta manera.

Código :

//loader
var loader:Loader = new Loader();
var request:URLRequest = new URLRequest("color.swf");
loader.load(request);
addChild(loader);
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete);
function onComplete(event:Event):void{
   //si queres llamar a la funcion directamente
   MovieClip(loader.getChildAt(0)).addEventListener(MouseEvent.MOUSE_DOWN,onClick);
   //si queres manejar el clip externo
   MovieClip(loader.getChildAt(0)).gotoAndStop("cualquierframe");
   //si queres pasarle directamente el root para llamarlo mas facil
   MovieClip(loader.getChildAt(0)).MainRoot=MovieClip(this);
}
//funcion a la que llamas desde el loader
function onClick(e:MouseEvent):void{
   trace(e)
}


a mi me funciona perfectamente y sin complicarme la existencia.. saludos. :wink:

Por phoxer

Claber

827 de clabLevel

4 tutoriales

Genero:Masculino  

Ing en Sistemas

msie7
Citar            
MensajeEscrito el 04 Abr 2008 03:17 pm
El punto de usar un singleton es que tienes una variable global, no importando donde estés y puedes tener un mejor control sobre la misma. No es complicarse la vida y menos cundo tienes un proyecto grande.

Saludos!

Por Cep

BOFH

1509 de clabLevel

9 tutoriales

1 ejemplo

Genero:Masculino   REC Bastard Operators From Hell

Web Developer

firefox
Citar            
MensajeEscrito el 04 Abr 2008 03:25 pm
igualmente no me referia directamente a vos. lellendo mi mensaje puede sonar algo directo :oops: pero lo digo en general. yo tabajo en una empresa y si hago proyectos medianos y grandes. pero el echo de usar clases a veses se va de las manos. lo que digo que si un objetivo se puede hacer con una simple funcion. porque hay que hacer una clase de todo eso??.

por ejemplo ayer me decian que tenia que hacer una clase para hacer un listado. :|
y yo decia porque una clase???. si con un simple bucle se puede hacer en 5 minutos. jaja. entendes?
por mas que sea un proyecto grande o chico me parece que a veses se piensa como se deven hacer las cosas y no en su funcionalidad final que es para cada proyecto. ojo entiendo lo de "reutilizar codigo" pero creo que las clases sirven para cosas MAS especificas nada mas.

igualmente es una forma de pensar y ovbio que yo puedo estar equivocado. ^^

Por phoxer

Claber

827 de clabLevel

4 tutoriales

Genero:Masculino  

Ing en Sistemas

firefox
Citar            
MensajeEscrito el 04 Abr 2008 03:39 pm
Refiriéndome a tu ejemplo, lo mas seguro es que te pidieran hacer una clase para no romper en encapsula miento, o para seguir los lineamientos del MVC. Todo depende de que patrón de diseño estés usando y demás.

Y no, las clases es el elemento fundamental de la POO, no solo son para cosas "mas especificas".

Por ejemplo, si tienes un objeto asi:

Código :

var obj:Object = new Object();
obj.name = "phoxer";
obj.clabLevel = 28;
..


Esta mal, tendrias que crear una clase tipo User por decir un ejemplo

Código :

package{
   public class User{
   
      protected var _name:String;
      protected var _level:uint;
      
      public function User($name:String, $level:uint){
         _name = $name;
         _level = $level;
      }   
      
      public function get level():uint{
         return _level;
      }
      public function set level($value:uint):void{
         _level = $value;
      }
      
      public function get name():String{
         return _name;
      }
      public function set name($value:String):void{
         _name = $value;
      }
   }
}


Pero repito todo depende de como programes ^^

Saludos.!

Por Cep

BOFH

1509 de clabLevel

9 tutoriales

1 ejemplo

Genero:Masculino   REC Bastard Operators From Hell

Web Developer

firefox
Citar            
MensajeEscrito el 04 Abr 2008 03:57 pm
eso es una cosa espesifica :wink:

igual yo tambien uso clases pero a lo que voy es que... :zzz:

Por phoxer

Claber

827 de clabLevel

4 tutoriales

Genero:Masculino  

Ing en Sistemas

firefox
Citar            
MensajeEscrito el 07 Abr 2008 04:15 am
Gracias por responder. En especial a phoxer que me dio una excelente idea para resolver mi problema.

He aquí el script (básico) resultante:

Código :

package {
   import flash.display.Sprite;
   import flash.display.Loader;
   import flash.net.URLRequest;
   import flash.events.Event;
   import flash.display.LoaderInfo;
   public class Padre extends Sprite{
      public var loader:Loader;
      public function Padre(){
         loader = new Loader();
         loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoadComplete);
         loader.load(new URLRequest('hijo/Hijo.swf'));
      }
      public function funcglobal(){
         trace("Se llamo al método funcglobal()");
      }
      private function onLoadComplete(e:Event):void {
         var loaderInfo:LoaderInfo = e.target as LoaderInfo;
         addChild(e.target.content);
         var swf:Object = loaderInfo.content;
         swf.MainRoot = Sprite(this);
         swf.init();
      }
   }
}


Tiene algunas diferencias con el script que phoxer escribió de ejemplo.
La linea MovieClip(loader.getChildAt(0)).MainRoot no copilaba correctamente. Preferí reemplazarla por:
var loaderInfo:LoaderInfo = e.target as LoaderInfo;
addChild(e.target.content);
var swf:Object = loaderInfo.content;
swf.MainRoot = Sprite(this); //(No planeo usar una linea de tiempo en el root, por lo tanto uso Sprite en lugar de MovieClip)

En el clip hijo el código va asi:

Código :

package {
   import flash.display.Sprite;
   public class Hijo extends Sprite {
      public var MainRoot;
      public function init():void {
         trace("Se ejecuta init() desde el clip externo");
         MainRoot.funcglobal();
      }
   }
}


Aún queda una pequeña cosa pendiente. En el clip hijo, la linea 4, no puedo definir a este tipo de variable como Sprite porque si lo hago el copilador de Flash verifica si realmente existe un método funcglobal en dicho sprite. Dejándolo en genérico me salvo de eso. Pero no es una "buena práctica" you know ^^ .

Por dzegarra

14 de clabLevel



Genero:Masculino  

Lima, Peru

firefox
Citar            
MensajeEscrito el 07 Abr 2008 02:24 pm
Tines que definir la variable MainRoot como tipo "Padre"

Código :

import Padre;
public var MainRoot:Padre;


Saludos!!

Por Cep

BOFH

1509 de clabLevel

9 tutoriales

1 ejemplo

Genero:Masculino   REC Bastard Operators From Hell

Web Developer

firefox
Citar            
MensajeEscrito el 07 Abr 2008 11:25 pm
Claro, podría crear una clase Padre que extienda a Sprite (al igual que la clase Padre real) solo para que el copilador no me lance un error. Aunque no se si esto funcione, puesto que la clase Padre de el clip Hijo no sera la misma que la clase Padre real.

Se trata de una aplicación que carga clips swf como aplicaciones dentro de contenedores (ventanas).

Por dzegarra

14 de clabLevel



Genero:Masculino  

Lima, Peru

firefox

 

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