比如我们有个如下的VO
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>
注意里面this.lblPrice.setStyle("color","black");这行代码.
因为itemrenderer是被循环使用的,系统只创建一定数量的itemrenderer来渲染所有的data,
所以如果没有这行代码,一旦一个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设计得一团乱麻.