MXMLとロジックを切り分ける
切り分けは必要?
MXMLファイル内にScriptタグを置くことで、簡単にロジックを記述することができます。
ですが、ロジックが長く、複雑になるにつれ、管理がしにくくなっていきます。
僕個人は、MXMLはあくまで”見た目(ビュー)”の部分を構築するのみで、スクリプトは記述しないことをルールにしています。
ちょっとした処理ならMXMLファイルに直接書いてしまったほうが楽なこともありますが、長い目で見れば、分けたほうが構成が統一され、ソースの管理がしやすくなると考えています。
外部スクリプトファイルを利用
もっとも単純な方法は、スクリプトファイルを別に用意し、スクリプトタグのsource属性に指定することで読み込む方法でしょう。
これはスクリプトタグ内に記述するのと同じ意味になります。
スコープは元のMXMLファイル(ひとつのクラス)の中のコードとして扱われます。
ただ、この方法でちょっと気になるのは、外部に切り離したファイル単体では、クラスとして成立していないということ。もとのMXMLファイルがひとつのクラスとして扱われ、外部ファイルはその一部となります。
この「宙ぶらりん感」が気になるかならないかは人それぞれですが、僕は気になりますw
IMXMLObjectインターフェースを実装する
これは、外部に切り離したロジックをひとつのクラスとして実装し、それをMXMLファイル内にタグ(プロパティと言い換えても間違いでは無いでしょうか?)として埋め込む方法です。
たとえば、MXMLファイルのトップレベルタグ下に以下のように記述します。
<logic:TestLogic id="testLogic" />
最初の”logic”となっている部分は名前空間(パッケージ)です。
カレントディレクトリに”logic”というサブディレクトリがあると仮定すると、この名前空間の定義は以下のようになります。
xmlns:logic="logic.*"
この記述をMXMLファイルのトップレベルタグに入れておくことで、このスコープ内で”logic:xxx”と書いた場合は、logicディレクトリ下のxxxというクラス(おそらくxxx.asファイル。もしくはxxx.mxmlかも)を読みにいきます。
先の例では、TestLogic.asというファイルを用意してあります。
このファイルにはTestLogicクラスを記述し、IMXMLObjectインターフェースを実装します。
IMXMLObjectインターフェースで定義されているメソッドは(現時点では)1つだけ。
initialized()メソッドです。
Flexでは、コンポーネント初期化後にこのメソッドが呼ばれます。
定義は以下。
public initialized( document:Object, id:String ):void;
第一引数にはこのオブジェクトを作成したドキュメントオブジェクト(つまるところ親コンテナかな)、第二引数にはドキュメントからこのオブジェクトを識別するための識別子(そのまんまid)が渡されます。
親コンテナへの参照をメンバ変数に持っておくのが定石です。
以下、よく見る基本形ですね。
public function initialized(document:Object, id:String):void
{
// _viewはメンバ変数、XXXはMXMLドキュメントの型。
_view = document as XXX;
// 初期化完了時のイベントをハンドリングしておく。
// 各コンポーネントへのアクセスは初期化後におこないます。
_view.addEventListener( FlexEvent.CREATION_COMPLETE, onCreationCompleteHandler );
}
まどろっこしく感じますが、慣れると構成がはっきり分けれますし、結構重宝します。
さらに一歩進めてみる
前例では、ロジックを専用の別クラスとして切り分けました。
ただし、MXMLドキュメントクラスとロジックのクラスは別物です。
では、MXMLドキュメントクラス自体をひとつのスクリプトファイルで記述できないのでしょうか?
実は、できます(その効果のほどは定かではありませんが・・・)。
たとえば、mx:Applicationのかわりに自分でmx.core.Applicationクラスを継承した”MyApp”というクラスを定義します。
MXMLファイルはこんな感じ。
<?xml version="1.0" encoding="utf-8"?>
<my:MyApp xmlns:my="*" styleName="plain">
</my:MyApp>
MXMLファイルと同じディレクトリにMyApp.asを置いてコンパイル。
真っ白い、何も無い画面がでます。
場合によっては使えるかもしれませんし・・・。
なんでもスクリプトで書きたい方はいいかもしれません。
ただ、やってみるといろんな落とし穴が待っているのですが・・・。

