2011年6月21日 星期二

不使用applicationDomain.getDefinition()前提下_載入外部swf_父層子層雙向取用類別

※※※ 1000622更新 : 目前發覺這個測試, 是在錯誤條件下得到的結果, 如果搬開child.swf到另一目錄, 就有錯誤發生. 暫時保留這個主題.


(一) 1000621_Main_1.fla 搭配主要類別(文件類別) Main_1_1000621.as,其元件庫中則有Ball元件綁定外部類別Ball.as,以上匯出為1000621_Main_1.swf。透過Main_1_1000621.as裡面的程式碼將載入外部的child.swf

(二) 被載入的外部swf 為child.swf, 由child.fla搭配Child.as所匯出.

(三) 1000621_Main_1.swf 載入child.swf後。

由於, child.swf 與 1000621_Main_1.swf  位於同一網域,且未以LoaderContext類別做其它設定
被載入的child.swf 與載入器所在的1000621_Main_1.swf,完成載入後,預設將位於同一安全性網域與同一應用程式網域
*** 藉由將載入的 SWF 檔置於相同的應用程式網域中,便可以直接存取其類別 *** 
*** 在載入器swf和被載入的swf之間,彼此所定義的類別為彼此可見 ***

(四) 所以,在Main_1_1000621文件類別中,可以直接調用Child類別建構式來建立其實體。
 var childObj:Child = new Child(); 
並調用其welcome()方法 - 
var message:String = childObj.welcome("Alice");

(五) 在Child.as中,可以直接調用Ball類別建構式,建立其實體。
var myParentBall:Ball = new Ball(275,200);
並調用其ballFunc()方法 - 
myParentBall.ballFunc();

(六) 以上, 質疑的是,是因為所解釋之原因,而能彼此擁有類別的可見度 ???
還是,因為命名空間的關係,而可被存取 ???


1000621_ApplicationDomain_1.rar 下載


Main_1_1000621
package  {
 
 import flash.display.Loader;
 import flash.display.Sprite;
 import flash.events.*;
 import flash.events.EventDispatcher;
 import flash.net.URLRequest;

 public class Main_1_1000621 extends Sprite {
  
  public static const LOADED:String = "loaded";
  public var testVar:String;
  private var ldr:Loader;
  
  public function Main_1_1000621() {
   this.testVar = "abc";
   ldr = new Loader();
   var req:URLRequest = new URLRequest("Child.swf");
   /*將外部Child.swf載入到目前應用程式網域*/
   /* ***藉由將載入的 SWF 檔置於相同的應用程式網域中,便可以直接存取其類別。*** */
   /*var ldrContext:LoaderContext = new LoaderContext(false,ApplicationDomain.currentDomain);*/
   ldr.contentLoaderInfo.addEventListener(Event.COMPLETE, completeHandler);
   ldr.load(req);
  }

  private function completeHandler(event:Event=null):void {
   trace("@Main_1_1000621 / completeHandler() / event.target.content : " + event.target.content);
   /*取得ldr載入之Child類別實體 - A法*/
   /*var childObj:Child = event.target.content as Child; */
   
   /*載入完成後, 建構一個Child類別實體, 指定給childObj - B法*/
   var childObj:Child = new Child();
   this.addChild(childObj);
   
   /*調用childObj實體的welcome()方法, */
   var message:String = childObj.welcome("Alice");
   trace("@Main_1_1000621 / completeHandler() / message : " + message);// Hello, Alice 
   
   /*載入完成後發送自訂事件*/
   var loadedEvent:Event = new Event(LOADED);
   childObj.dispatchEvent(loadedEvent);
   trace("@Main_1_1000621 / completeHandler() / this.dispatchEvent(loadedEvent) : " + this.dispatchEvent(loadedEvent));
  }
  
  public function hello():void{
   trace("@Main_1_1000621 / hello() : Hello!!! Baby!!!");
  }
 }
}



Child
package {

 import flash.display.Sprite;
 import flash.events.Event;
 import flash.system.ApplicationDomain;
 
 public class Child extends Sprite {
  
  public var childVar:String;

  public function Child() {
   this.childVar = "@Child : I am from ChildClass";
   /*偵聽Main_1_1000621.LOADED 之載入完成事件*/
   this.addEventListener(Main_1_1000621.LOADED,loadedHandler);
   this.addEventListener(Event.ADDED_TO_STAGE,addedToStage);
   return;
  }
  
  public function loadedHandler(event:Event):void{
   trace("@Child / loadedHandler() / event.type : " + event.type);
   
   /*取得父類別實體*/
   var myParent:Main_1_1000621 = this.parent as Main_1_1000621;
   trace("@Child / loadedHandler() / myParent : " + myParent);
   
   /*調用父類實體的hello()方法*/
   myParent.hello();
   /*trace(myParent.testVar);*/
   return;
  }
  
  public function addedToStage(event:Event):void{
   this.removeEventListener(Event.ADDED_TO_STAGE,addedToStage);
   this.addEventListener(Event.REMOVED_FROM_STAGE,removedFromStage);
   
   /*Ball類別為1000621_Main_1.fla元件庫中Ball元件所綁定外部自訂類別*/
   
   /*由於, child.swf 與 1000621_Main_1.swf  位於同一網域, 且未以LoaderContext類別做其它設定*/
   /*被載入的child.swf 與載入器所在的1000621_Main_1.swf, 完成載入後, 預設將位於同一安全性網域與同一應用程式網域*/
   /* ***藉由將載入的 SWF 檔置於相同的應用程式網域中,便可以直接存取其類別。*** */
   
   /*因此,在這裡Child類別中,可以直接調用Ball類別建構式,建立其類別實體, 並調用Ball類別實體方法*/
   var myParentBall:Ball = new Ball(275,200);
   myParentBall.ballFunc();
   this.parent.addChild(myParentBall);
   return;
  }
  
  public function removedFromStage(event:Event):void{
   this.removeEventListener(Event.REMOVED_FROM_STAGE,removedFromStage);
   return;
  }

  public function welcome(_name:String):String {
   return "Hello, " + _name;
  }
 }
}


Ball
package  {
 
 import flash.display.SimpleButton;
 import flash.events.Event;
 
 public class Ball extends SimpleButton {
  
  public var thisX:Number;
  public var thisY:Number;
  
  public function Ball(_x:Number,_y:Number) {
   this.addEventListener(Event.ADDED_TO_STAGE,addedToStage);
   this.thisX = _x;
   this.thisY = _y;
   return;
  }
  
  public function addedToStage(event:Event):void{
   this.removeEventListener(Event.ADDED_TO_STAGE,addedToStage);
   this.addEventListener(Event.REMOVED_FROM_STAGE,removedFromStage);
   this.x = this.thisX;
   this.y = this.thisY;
   return;
  }
  
  public function removedFromStage(event:Event):void{
   this.removeEventListener(Event.REMOVED_FROM_STAGE,removedFromStage);
   return;
  }
  
  /*此例, Ball類別的這個ballFunc()方法,將在child.swf 被1000621_Main_1.swf 載入後,被Child類別實體調用*/
  public function ballFunc():void{
   trace("@Ball / ballFunc : I am from Ball Class");
  }
 }
 
}

沒有留言: