2012-05-01 33 views
0

我期待在主時間線中聲明一個GLOBAL VAR。as3聲明一個GLOBAL變量 - 在TIMELINE/CLASSELI之外

然後,我需要從另一個外部加載的SWF中訪問該GLOBAL VAR。

問題:

如何創建主時間軸的全局變量?

如何在外部加載的swf文件中訪問該var?

+0

-1沒有其他原因,而不是事實,總有一個更好的解決方案比使用全球。任何OOP語言的全局都是一種恥辱。 – 2012-05-01 03:26:18

+1

AS3不僅僅是OOP,而且全局變量確實有一個地方 - 例如'Event'名稱。沒有理由否定壞的設計理念。 。 。畢竟,這就是評論的意思。 – iND

+0

AS3不只是OOP。好的...請隨意擴展那個?什麼是程序語言? *交叉眼睛,使遲鈍的臉*。無論如何,對於高度特定的類設計,有一些標準的定義類型,並且正如OP所說,在全局名稱空間中使用全局變量,以便任何加載的內容都可以從任何地方訪問它,這是相距甚遠的。你真的想通過與Class.CLASS_TYPE的比較來證明global.myVar? – 2012-05-01 11:59:26

回答

1

如果這些變量是您只想設置一次且永遠不會更改的變量,則可以創建一個包含靜態常量的類。

package 
{ 
    public class Env 
    { 
     public static const WHATEVER:String = "Whatever!"; 

     public function Env() 
     {} 
    } 
} 

然後,你可以稍後訪問它們在你的程序像這樣:

trace(Env.WHATEVER); 

但是,如果你想要,可以改變全局變量,我喜歡用一個單獨的類來處理這個問題。

package 
{ 
import flash.events.EventDispatcher; 

public class Control extends EventDispatcher 
{ 
    //--------------------------------------- 
    // PRIVATE & PROTECTED INSTANCE VARIABLES 
    //--------------------------------------- 

    private static var _instance:Control; 

    //--------------------------------------- 
    // PUBLIC VARIABLES 
    //--------------------------------------- 

    public var whatever:String = "Whatever"; 

    //--------------------------------------- 
    // PUBLIC METHODS 
    //--------------------------------------- 

    public static function get instance():Control 
    { 
     return initialize(); 
    } 

    public static function initialize():Control 
    { 
     if (_instance == null) 
     { 
      _instance = new Control(); 
     } 
     return _instance; 
    } 

    //--------------------------------------- 
    // CONSTRUCTOR 
    //--------------------------------------- 

    public function Control() 
    { 
     super(); 
     if (_instance != null) 
     { 
      throw new Error("Error:Control already initialised."); 
     } 
     if (_instance == null) 
     { 
      _instance = this; 
     } 
    } 

} 
} 

這裏的區別是,你需要抓住你單身的情況下才可以得到它裏面有什麼。它看起來有點像這樣。只要更改

private var _control:Control = Control.instance; 
// Reading a global variable 
trace(_control.whatever); 
// Change a global variable 
_control.whatever = "Foobar!"; 

所以「無所謂」,這個變量將所有加載的SWF改變。如果你想真的很喜歡它,你可以在你的單例中使用getters/setters而不是簡單的公共變量。

2

首先,您不應該使用任何global/static state。在你的情況下,這甚至是更多是真實的,因爲單身人士是跨越不同應用程序域的對接的皇家痛苦。

相反,你應該使用一種叫做Dependency Injection的東西。把你的小swfs想象成飢餓的孤兒。當他們已經裝載時,他們不會跑到你的主要swf並挑選它的口袋。相反,主要瑞士銀行大量地將資金壓入他們的小手中。

那麼,我們該如何做到這一點?一種方法是我們可以將對其Document類的引用編譯成主要的swf,然後我們可以設置該類所公開的變量。但是,這可能會相當沉重,並不是真的有必要。

相反,你可以寫一些名爲Interface的東西,它定義了一個孤兒的「想法」。

它可能是這個樣子:

public interface IOrphan { 
    function get alms():Number; 
    function set alms(value:Number):void; 
} 

請注意,你必須使用getter和setter方法與界面,因爲你不能用它們來定義香草變量。然而,去上班了偉大的我們的實際孤兒:

public class Oliver implements IOrphan { 
    private var _alms:Number; 
    private var _totalAlms:Number; 
    public var tf:TextField;//put this on stage and allow Flash to populate automatically 
    public function get alms():Number { 
     return _alms; 
    } 
    public function set alms (value:Number):void { 
     _alms = value; 
     _totalAlms += _alms; 
     updateAlmsMessage(); 
    } 
    private function updateAlmsMessage():void { 
     tf.text = 'That was a donation of ' + _alms + '.\n' 
       'I now have ' _totalAlms + '.\n' 
       'Please, sir, can I have some more?'; 
    } 
} 

現在,所有你需要做的就是填充負載變量。有幾種方法可以做到這一點,如watching the stage爲IOlivers被加載,或者你可以更直接看:

private function loadSwf(url:String):void { 
      var loader:Loader = new Loader(); 
      loader.contentLoaderInfo.addEventListener(Event.COMPLETE, completeHandler); 
      var request:URLRequest = new URLRequest(url); 
      loader.load(request); 
      addChild(loader); 
} 

private function completeHandler(e:Event):void { 
    ((e.target as LoaderInfo).content as IOrphan).alms = .25; 
}