Mix-in の使用
Mix-in を使用するには、Mix-in クラスをインスタンス化し、そのクラスのメソッドをカスタムクラスのプロトタイプオブジェクトに適用します。これで、Mix-in したクラスのメソッドをカスタムクラスのインスタンスから呼び出せるようになります。この手順を、GeekStoreDepartment というカスタムクラスを例にとって次に説明します。
Mix-in を使用するには :
- 必要なクラスを読み込みます。次のように、使用する Mix-in と mx.core.Application クラスを読み込みます。
import mx.events.EventDispatcher; import mx.core.Application;
mx.core.Application クラスを読み込むのは、カスタムクラス内で Flex アプリケーションのスコープにアクセスする際に、パッケージ名全体を記述しなくて済むようにするためです。必須ではありません。
- 次のように、Mix-in クラスの静的インスタンスを宣言します。
static var evtDispatcher = mx.events.EventDispatcher;
これは、後の手順で静的メソッドを呼び出す前に Mix-in を Flash に認識させるための明示的な宣言です。依存関係を解決するためだけに実行します。
カスタムクラスの
Initialize()メソッドで、次のようにカスタムクラスのプロトタイプオブジェクトをインスタンス化します。var p = GeekStoreDepartment.prototype;
- 次のように、Mix-in クラスの
initialize()メソッドを呼び出してプロトタイプオブジェクトを渡します。EventDispatcher.initialize(p);
- (オプション)
trueを返します。最終的に、
Initialize()メソッドは次のようになります。static function Initialize() :Boolean { var p = GeekStoreDepartment.prototype; EventDispatcher.initialize(p); return true; } - カスタムクラスの
Initialize()メソッドを呼び出し、戻り値を静的変数に設定します。カスタムクラスのInitialize()メソッドでは、最初の呼び出しに対して true を返します。static var mixit :Boolean = GeekStoreDepartment.Initialize();
その結果、Flex から
Initialize()メソッドは 1 回しか呼び出されません。この変数は静的変数なので、オブジェクトがインスタンス化されるのはクラスが最初に使用される際の 1 回だけです。アプリケーションが動作している間は再度呼び出す必要はないため、処理のオーバーヘッドもメモリ消費量も小さくなります。 - Mix-in したメソッドを呼び出す必要がある場合は、それらのメソッドを宣言します。EventDispatcher クラスの場合は、
addEventListener()、removeEventListener()、およびdispatchEvent()メソッドが該当します。これらのメソッドを追加するには、次のコードを使用します。var addEventListener:Function; var removeEventListener:Function; var dispatchEvent:Function;
- Mix-in したメソッドは、カスタムクラス自体にメソッドと定義した場合と同様にいつでも呼び出すことができます。次の例では、カスタムクラスの
setProperty()メソッドが呼び出されたときに modelChanged イベントを送出します。function setProperty(name:String, propertyValue, broadcastChange:Boolean) { // 通常はもっと複雑な処理になりますが、この例では単に // ラベルの値を "White" に変更します。 products[0].label="White"; // 適切な方法で渡されるようにイベントオブジェクトを引数に指定して、dispatchEvent を呼び出します。 dispatchEvent( {type:"modelChanged" } ); }
次のコード例は、ここまで説明した手順を示す TreeDataProvider のカスタムクラスです。実際に動作するように他のクラスロジックも追加しています。
class GeekStoreDepartment implements mx.controls.treeclasses.TreeDataProvider {
import mx.core.Application;
import mx.events.EventDispatcher;
// 静的メソッド呼び出しの前に依存関係を強制的に解決させます。
static var evtDispatcher = mx.events.EventDispatcher;
static function Initialize() :Boolean {
var p = GeekStoreDepartment.prototype;
EventDispatcher.initialize(p);
return true;
}
// Initialize() メソッドを呼び出します。
static var mixit :Boolean = GeekStoreDepartment.Initialize();
// Mix-in したメソッドを宣言します。
var dispatchEvent:Function;
var addEventListener:Function;
var removeEventListener:Function;
// 単純な配列
var products:Array = [
{label:"Red"},
{label:"Green"},
{label:"Blue"}
];
// カスタム DataProvider としてのコードをここに記述します。
// ここでは、TreeDataProvider の最小限の実装を示します。
function hasChildNodes() :Boolean {return true;}
function getChildNodes() :Array {return products;}
function getProperty(name :String) {return products[name];}
function setProperty(name :String, propertyValue, broadcastChange:Boolean) {
products[0].label="White";
dispatchEvent( {type:"modelChange" } );
}
function isTreeDataProvider() :Boolean {
return true;
}
function indexOf(item:Object):Number {
for (var i=0; i<products.length; i++) {
if (products[i] == item) {
return i;
}
}
}
// 残りの TreeDataProvider メソッドについてスタブのみ用意します。
function getData() :Object { }
function setData(data :Object) {}
function addTreeNode(arg,data) {}
function addTreeNodeAt(index,arg,data) {}
function removeTreeNodeAt(index) {}
function removeTreeNode(){}
function removeAll(){}
function getTreeNodeAt(index :Number){}
}
次の MXML ファイルでは、このカスタム TreeDataProvider をインスタンス化し、setProperty() メソッドを呼び出すことで、Mix-in した dispatchEvent() メソッドへの呼び出しをトリガします。
<?xml version="1.0"?>
<mx:Application xmlns:mx="http://www.macromedia.com/2003/mxml" xmlns:local="*">
<local:GeekStoreDepartment id="myDP" />
<mx:Tree id="myTree" dataProvider="{myDP}" />
<mx:TextArea id="myTA" />
<mx:Button click="myTA.text=myTree.dataProvider.setProperty('White');" label="Click Me" />
</mx:Application>

