« 2007年09月 | | 2008年08月 »

Flex の Module 開発 (2) - ロード側

少し間が開いてしまいましたが、前回 作成したモジュールを利用するコード(シェル)を作成していきます。

MXML からロード

MXML でロードするには <mx:ModuleLoader> タグを利用します。

次のように url プロパティでモジュールの場所を指定し、loadModule() メソッドを呼べばロードできます。

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
  <mx:Script>
    <![CDATA[
      private function load(ml:ModuleLoader):void {
        ml.url = "MyModuleA.swf";
        ml.loadModule();
      }

      private function onReady(ml:ModuleLoader):void {
        var myModule:IMyModule = ml.child as IMyModule;
        if(myModule) {
          myModule.setText("loaded");
        }
      }
    ]]>
  </mx:Script>

  <mx:ModuleLoader id="ml1" ready="onReady(ml1)"/>
  <mx:Button click="load(ml1)" label="load"/>

  <mx:ModuleLoader id="ml2" ready="onReady(ml2)"/>
  <mx:Button click="load(ml2)" label="load"/>

</mx:Application>

モジュールのダウンロードが完了すると、ModuleLoader 内にロードした SWF が addChild されます。ModuleLoader には同時に1つのモジュールしかロードできません。複数のモジュールをロードするためには、モジュールの個数分の ModuleLoader を作成してください。

1度ロードしたモジュールは ModuleManager によりキャッシュされ、2回目以降の loadModule() はネットワークアクセスなしに行うことができます。キャッシュを削除するには、ModuleLoader クラスの unloadModule() メソッドを呼びます。

ちなみに、ModuleLoader クラスは VBox を継承したコンテナです。ModuleLoader クラスが UIComponent や Container ではなく、VBox を継承しているところに違和感を感じた方もいるかもしれません。これは、ModuleLoader クラスを継承して、ロードするための情報を表示させるときに便利だからです。具体例は Roger Gonzalez: My MAX preso... からダウンロードできる demos/Insurance/MyModuleLoader.mxml をご覧ください。この例では、MoModuleLoader の中に、ロード開始のボタンとロード状況を表すプログレスバーなどを表示しています。

ActionScript からロード

ActionScript からロードする場合も、MXML の場合と同様です。ModuleLoader クラスのインスタンスを生成し、loadModule() を呼び出せば OK です。

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
  applicationComplete="init()">
  <mx:Script>
    <![CDATA[
      import mx.events.ModuleEvent;
      import mx.modules.*;

      private function init():void {
        var ml:ModuleLoader = new ModuleLoader();
        ml.url = "MyModuleA.swf";
        addChild(ml);
        ml.addEventListener("ready", function(e:ModuleEvent):void {
          onReady(ml);
        });
        ml.loadModule();
      }

      // onReady 関数は先ほどと同様
    ]]>
  </mx:Script>
</mx:Application>

ここでは、さらに掘り下げて ModuleLoader を使わない方法を紹介しましょう。ModuleLoader は内部で ModuleManager や IModuleInfo といったクラス利用しています。これらのクラスに直接アクセスすることで、多少煩雑にはなりますが、より細かくモジュールの動作を制御することができます。

以下のコードをご覧ください。

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
  applicationComplete="init()">
  <mx:Script>
    <![CDATA[
      import flash.display.DisplayObject;
      import flash.display.Sprite;
      import mx.events.ModuleEvent;
      import mx.modules.*;

      private function init():void {
        var module:IModuleInfo = ModuleManager.getModule("MyModuleA.swf");
        module.addEventListener("ready", readyHandler);
        module.load(null);
      }

      private function readyHandler(e:ModuleEvent):void {
        var module:IModuleInfo = e.module;

        var d1:DisplayObject = module.factory.create() as DisplayObject;
        addChild(d1);
        var mod1:IMyModule = d1 as IMyModule;
        if(mod1) {
          mod1.setText("1");
        }

        var d2:DisplayObject = module.factory.create() as DisplayObject;
        addChild(d2);
        var mod2:IMyModule = d2 as IMyModule;
        if(mod2) {
          mod2.setText("2");
        }
      }
    ]]>
  </mx:Script>
</mx:Application>

この例では、ModuleManager.getModule() メソッドを利用して、IModuleInfo を取得しています。まず、IModuleInfo 経由でモジュールのロードが完了の通知を受け取ります。イベントハンドラでは、factory.create() を利用してインスタンスを生成し、これを addChild しています。

1つのモジュールから複数のインスタンスを生成しているところがポイントです。

まとめ

モジュールをロード側する方法を紹介しました。大きく分けて次の2つの方法があります。

  • 簡単に実装するなら ModuleLoader を使う
  • 少し込み入った使い方をするなら ModuleManager や IModuleInfo を使う

2007-2009 CO-CONV,Corp

ブログ内に記載されている社名および製品名は各社の商標または登録商標です。