2008/12/19

labelFunctionかItemRendererか。それとあとFormatter (4)

前回の続き。


[Bindable]
public var format:Function;

とやった上で、format プロパティをセットし直すことで再フォーマットさせる、という風にして解決を図ったのだけれと、このformatプロパティをセットし直さないといけない、というのと外から変えられてしまうのがどうもなぁ、というところ。

とりあえず外から変えられないようにgetterを作ってみたけれど、コンパイラに怒られるはバインディングされないわでダメだった。


で、これを解決すべくググってみたりとかして調べてみた結果、実は読み取り専用プロパティでもデータバインディング元にできるということが判明。
ていうか、探せばFlex SDKのなかにたくさん溢れているようで、たとえばRadioButtonGroupのnumRadioButtonsプロパティとか。

ポイントとしては、


  1. getterにイベント名付きの[Bindable]タグを付けて宣言

    e.g.)

    [Bindable(event="hogeChange")]
    public function get hoge() { return _hoge; }


  2. バインドした先にプロパティの変更を通知したい場合、[Bindable]タグでつけたイベントをディスパッチする

    e.g.)

    private function setHoge(value:String)
    {
    _hoge = value;
    dispatchEvent(new Event("hogeChange"));
    }




で良いらしい。

しかも、もうちょっといろいろと試してみると、別にgetterでなくとも、関数に直接[Bindable(event="hogeChange")]を書いてもいいらしいということがわかった。
ちょっとわけがわからなくなりそうだけど、要は、関数に[Bindable]を付けておけば、データバインディングでその関数を使っているところに対して、好きなタイミングでその関数をコールさせることができるということか。
あるいは、好きなタイミングでデータバインディング式を評価させることが可能か。
う~ん、今回の用途にぴったり。

上記を踏まえて、以下のようにして作ってみた。


[Bindable]
public function get unit():int { return _unit; }
public function set unit(value:int):void
{
_unit = value;
dispatchEvent(new Event("formatChange"));
}

[Bindable(event="formatChange")]
public function format(item:Object, column:DataGridColumn):String
{
(略)
}


なんだ、逆にだいぶ簡単になっちゃったじゃん。

あれ、でもこのオブジェクト、別にEventDispatcherを継承してるわけじゃないんだけど。。。
Mix-Inってやつか?まぁ、あんまり気にしないでみよう・・・。

さて、これでだいぶいい感じになってきたけど、どうもしっくりきてないのが、Formatterの存在。
Flex標準で提供されている割には、いまいちlabelFunctionとかと相性が悪いんだよね。
結局、いちいち今まで作ってきたようなオブジェクトを作って、その中でFormatterを作って利用、みたいな流れなので、面倒。
最後はこれを何とかしてみたい。