Flex的一点入门经验(8)--itemRenderer与外部组件的通信

比如我们有个如下的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设计得一团乱麻.

你可能感兴趣的:(Flex)