2010年4月6日火曜日

Flex入門~続!アイテムレンダラーとアイテムエディタ編~だじぇ

前回の続きです。
今回はアイテムレンダラーとアイテムエディタを自作のコンポーネントとして作成してみます。

まずベースとなるソースです。
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
    <mx:Script>
    <![CDATA[
        [Bindable]
        private var userDataList:Array = [
            { userid: 1, name: "家忍和馬", age: 28, birthday: '1982/03/23' },
            { userid: 2, name: "家忍正孝", age: 30, birthday: '1980/12/12' },
            { userid: 3, name: "家忍果凛", age: 32, birthday: '1978/01/10' }
        ];
    ]]>
    </mx:Script>
    
    <mx:DataGrid dataProvider="{userDataList}" width="500">
        <mx:columns>
            <mx:DataGridColumn dataField="userid" width="100" />
            <mx:DataGridColumn dataField="name" width="100" />
            <mx:DataGridColumn dataField="age" />
        </mx:columns>
    </mx:DataGrid>
</mx:Application>
これに自作コンポーネントをアイテムレンダラーやアイテムエディタとして指定してみます。

アイテムレンダラー
自作のコンポーネントといっても特別なことはなく、例えば次のような感じになります。
<?xml version="1.0" encoding="utf-8"?>
<mx:HBox xmlns:mx="http://www.adobe.com/2006/mxml">
    <mx:Label text="{data.age}"></mx:Label>
    <mx:Label text="(生年月日:{data.birthday})"></mx:Label>
</mx:HBox>
{data.age}や{data.birthday}の「data」は表示するデータのオブジェクトで、そのオブジェクトのプロパティ「age」「birthday」のデータを表示することを意味しています。

これをアイテムレンダラーとして指定すると次のようになります。
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
    <mx:Script>
    <![CDATA[
        [Bindable]
        private var userDataList:Array = [
            { userid: 1, name: "家忍和馬", age: 28, birthday: '1982/03/23' },
            { userid: 2, name: "家忍正孝", age: 30, birthday: '1980/12/12' },
            { userid: 3, name: "家忍果凛", age: 32, birthday: '1978/01/10' }
        ];
    ]]>
    </mx:Script>
    
    <mx:DataGrid dataProvider="{userDataList}" width="500">
        <mx:columns>
            <mx:DataGridColumn dataField="userid" width="100" />
            <mx:DataGridColumn dataField="name" width="100" />
            <mx:DataGridColumn dataField="age" itemRenderer="my.blogger.memo.MyComponent" />
        </mx:columns>
    </mx:DataGrid>
</mx:Application>
これは表示するデータの全てのプロパティにアクセスできるのが特徴です。
これなら他のプロパティの値などを条件にして表示を切り替えたりできそうです。
<・・・ visible="{data.age &lt; 30}" />とか。

アイテムエディタ
基本的にはアイテムレンダラーと同じです。
ただ、アイテムエディタで値を変更したらアイテムレンダラーには変更後の値が表示されないとおかしいので、アイテムエディタ⇒アイテムレンダラーに値を渡すことになります。editorDataFieldを使うと、アイテムエディタのどのプロパティの値をアイテムレンダラーに表示するかを指定するみたいです。
あと、アイテムエディタに渡ってくるdataオブジェクトはDataGridのdataProviderへの参照なので、それを保持しておけば直接変更できるみたい。

ということで、こんな感じにしました。
■アイテムレンダラー(MyRendererComponent)
<?xml version="1.0" encoding="utf-8"?>
<mx:HBox xmlns:mx="http://www.adobe.com/2006/mxml" horizontalGap="0">
    <mx:Label text="{data.age}"></mx:Label>
    <mx:Label text="(生年月日:"></mx:Label>
    <mx:Label text="{data.birthday}"></mx:Label>
    <mx:Label text=")"></mx:Label>
</mx:HBox>
■アイテムエディタ(MyEditorComponent)
<?xml version="1.0" encoding="utf-8"?>
<mx:HBox xmlns:mx="http://www.adobe.com/2006/mxml" horizontalGap="0">
    <mx:Script>
    <![CDATA[
        import mx.events.NumericStepperEvent;
        import mx.controls.DateField;

        // 元のデータへの参照です。
        public var tmpData:Object;
        // アイテムレンダラーに返す値になります。
        [Bindable]
        public var age:int;
        [Bindable]
        private var birthday:String;
        
        override public function set data(data:Object):void {
            this.tmpData = data;
            this.age = data.age;
            this.birthday = data.birthday;
        }
        
        private function handleChange(e:NumericStepperEvent):void {
            var deltaAge:int = age - e.value;   // 修正            this.age = e.currentTarget.value;
            var date:Date = DateField.stringToDate(String(birthdayDateField.text), 'YYYY/MM/DD');
            var year:int = date.getFullYear() + deltaAge;   // 修正
            date.setFullYear(year);
            this.birthday = DateField.dateToString(date, 'YYYY/MM/DD');
            // 元のデータを更新
            tmpData.age = this.age;
            tmpData.birthday = this.birthday;
        }
        
    ]]>
    </mx:Script>
    
    <mx:NumericStepper value="{age}" minimum="0" maximum="120" change="handleChange(event)"></mx:NumericStepper>
    <mx:Label text="(生年月日:"></mx:Label>
    <mx:Label id="birthdayDateField" text="{birthday}" ></mx:Label>
    <mx:Label text=")"></mx:Label>
</mx:HBox>
■メイン
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
    <mx:Script>
    <![CDATA[
        [Bindable]
        private var userDataList:Array = [
            { userid: 1, name: "家忍和馬", age: 28, birthday: '1982/03/23' },
            { userid: 2, name: "家忍正孝", age: 30, birthday: '1980/12/12' },
            { userid: 3, name: "家忍果凛", age: 32, birthday: '1978/01/10' }
        ];
    ]]>
    </mx:Script>
    
    <mx:DataGrid dataProvider="{userDataList}" width="500" editable="true">
        <mx:columns>
            <mx:DataGridColumn dataField="userid" width="100" />
            <mx:DataGridColumn dataField="name" width="100" />
            <mx:DataGridColumn dataField="age" editorDataField="age"
              itemRenderer="my.blogger.memo.MyRendererComponent"
              itemEditor="my.blogger.memo.MyEditComponent" />
        </mx:columns>
    </mx:DataGrid>
</mx:Application>
まあ、うまくいったかなぁ?
ActionScriptで書けばもう少しきれいになるんだろうけど( ゚Д゚)マンドクセー。
もう少し慣れたらやってもいいかな?

<追記>
思いっきりバグっていたので修正しました。
今見ると生年月日なんて変わることないんだけどなぁ・・・とか思ったり。
連動できたからおkってことにしとこう。
体調激ワル、喉痛い・・・。

0 コメント:

コメントを投稿

ニコニコ動画ランキング

 
無添加キャットフード通販専門店 ネコまんま