Flexの入門経験(8)--itemRendererと外部コンポーネントの通信
7052 ワード
例えば次のようなVOがあります
今datagridで、価格が50より大きいものを赤で表示したいのですが、次のようなコードが使えます.
中に気をつけてlblPrice.setStyle("color","black");この行のコード
itemrendererはリサイクルされるため、システムはすべてのdataをレンダリングするために一定数のitemrendererしか作成しません.
この行のコードがなければitemrendererがcolorをredに設定するとblackにはなりません
しかしhard codeの50は本当に不快なのでtextinputを作って、しきい値をユーザーが入力した数値にします
datagridのdataproviderのarraycollectionに対してrefreshメソッドを呼び出すことで、datagridコンポーネントの状態をリフレッシュすることができることに注意する.
でもここでitemrendererはouterDocumentを使います.txtInputNumberのように外部コントロールにアクセスし、
実はこのlimit値はdatagridに入れるべきで、このようにdatagridとitemrendererはもっとよくパッケージされています.
Datagridをカスタマイズします
そしてこのように使います
GridItemRendererではgridに参照できるgrid属性があり、gridのdataGrid属性はdataGridに参照できる.
GridとDataGridの違いが全く分からず、ドキュメントにもぼろぼろに書かれていて、実際にspark Gridコントロールの使用例が見つからず、ここのAPIがめちゃくちゃに設計されているような気がします.
package com.crap.vo{
public class Product
{
public function Product(name:String,price:Number)
{
this.name=name;
this.price=price;
}
public var name:String;
public var price:Number;
}
}
今datagridで、価格が50より大きいものを赤で表示したいのですが、次のようなコードが使えます.
<s:DataGrid dataProvider="{productAC}">
<s:columns>
<s:ArrayList>
<s:GridColumn dataField="name"/>
<s:GridColumn>
<s:itemRenderer>
<fx:Component>
<s:GridItemRenderer>
<fx:Script>
<![CDATA[
import com.crap.vo.Product;
override public function set data(data:Object):void{
super.data=data;
var product:Product=data as Product;
if(product.price>50){
this.lblPrice.setStyle("color","red");
}else{
this.lblPrice.setStyle("color","black");
}
}
]]>
</fx:Script>
<s:Label text="{data.price}" id="lblPrice">
</s:Label>
</s:GridItemRenderer>
</fx:Component>
</s:itemRenderer>
</s:GridColumn>
</s:ArrayList>
</s:columns>
</s:DataGrid>
中に気をつけてlblPrice.setStyle("color","black");この行のコード
itemrendererはリサイクルされるため、システムはすべてのdataをレンダリングするために一定数のitemrendererしか作成しません.
この行のコードがなければitemrendererがcolorをredに設定するとblackにはなりません
しかしhard codeの50は本当に不快なのでtextinputを作って、しきい値をユーザーが入力した数値にします
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
minWidth="955" minHeight="600">
<fx:Declarations>
</fx:Declarations>
<s:layout>
<s:VerticalLayout/>
</s:layout>
<fx:Script>
<![CDATA[
import com.crap.vo.Product;
import mx.collections.ArrayCollection;
[Bindable]
public var productAC:ArrayCollection=new ArrayCollection(
[new Product("product1",43),
new Product("product2",35),
new Product("product3",108)]);
]]>
</fx:Script>
<s:TextInput id="txtInputNumber" change="productAC.refresh();" >
</s:TextInput>
<s:DataGrid dataProvider="{productAC}" id="dgProduct">
<s:columns>
<s:ArrayList>
<s:GridColumn dataField="name"/>
<s:GridColumn>
<s:itemRenderer>
<fx:Component>
<s:GridItemRenderer>
<fx:Script>
<![CDATA[
import com.crap.vo.Product;
override public function set data(data:Object):void{
super.data=data;
var product:Product=data as Product;
if(product.price> Number(outerDocument.txtInputNumber.text) ){
this.lblPrice.setStyle("color","red");
}else{
this.lblPrice.setStyle("color","black");
}
}
]]>
</fx:Script>
<s:Label text="{data.price}" id="lblPrice">
</s:Label>
</s:GridItemRenderer>
</fx:Component>
</s:itemRenderer>
</s:GridColumn>
</s:ArrayList>
</s:columns>
</s:DataGrid>
</s:Application>
datagridのdataproviderのarraycollectionに対してrefreshメソッドを呼び出すことで、datagridコンポーネントの状態をリフレッシュすることができることに注意する.
でもここでitemrendererはouterDocumentを使います.txtInputNumberのように外部コントロールにアクセスし、
実はこのlimit値はdatagridに入れるべきで、このようにdatagridとitemrendererはもっとよくパッケージされています.
Datagridをカスタマイズします
package com.crap.compenent{
import mx.collections.ArrayCollection;
import spark.components.DataGrid;
public class CrapDataGrid extends DataGrid
{
public function CrapDataGrid()
{
super();
}
private var _limit:Number;
public function get limit():Number
{
return _limit;
}
public function set limit(value:Number):void
{
_limit = value;
ArrayCollection(this.dataProvider).refresh();
}
}
}
そしてこのように使います
<s:TextInput id="txtInputNumber" text="">
</s:TextInput>
<compenent:CrapDataGrid dataProvider="{productAC}" id="dgProduct" limit="{Number(txtInputNumber.text)}">
<compenent:columns>
<s:ArrayList>
<s:GridColumn dataField="name"/>
<s:GridColumn>
<s:itemRenderer>
<fx:Component>
<s:GridItemRenderer>
<fx:Script>
<![CDATA[
import com.crap.compenent.CrapDataGrid;
import com.crap.vo.Product;
override public function set data(data:Object):void{
super.data=data;
var product:Product=data as Product;
var crapDataGrid:CrapDataGrid=this.grid.dataGrid as CrapDataGrid;
if(product.price> crapDataGrid.limit ){
this.lblPrice.setStyle("color","red");
}else{
this.lblPrice.setStyle("color","black");
}
}
]]>
</fx:Script>
<s:Label text="{data.price}" id="lblPrice">
</s:Label>
</s:GridItemRenderer>
</fx:Component>
</s:itemRenderer>
</s:GridColumn>
</s:ArrayList>
</compenent:columns>
</compenent:CrapDataGrid>
GridItemRendererではgridに参照できるgrid属性があり、gridのdataGrid属性はdataGridに参照できる.
GridとDataGridの違いが全く分からず、ドキュメントにもぼろぼろに書かれていて、実際にspark Gridコントロールの使用例が見つからず、ここのAPIがめちゃくちゃに設計されているような気がします.