`
schy_hqh
  • 浏览: 542198 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

(十一)为DataGrid指定项目呈现器(单元格内显示图片和按钮)

 
阅读更多
1.使用DataGrid组件展现数据(表格),以交互方式操作其中的行和列
2.自定义项目呈现器,在DataGrid的某列重载默认行为(默认显示文本,修改为显示图片)
3.在列中以自定义方式进行排序
4.AdvancedDataGrid的功能:排序、修改样式、分组和摘要数据

Flex4中,组合使用Spark和MX空间能够实现任何想要的功能
例如Form、DataGrid和AdvancedDataGrid在Spark中没有提供,那么就使用MX版
MX与Spark能够很好的集成,共同为开发提供组件支持

DataGrid 数据网格,按行和列呈现一个表格
DataGridColumn  定义某一列
dataField  将数据集中的列定位到DataGrid中的特定列

为DataGridColumn添加内联的编辑控件
    当焦点位于单元格时,只要将editable属性设为true即可
    默认的编辑控件是文本域
    通过itemEditor和editorDataField属性,可以指定编辑数据时所使用的编辑器
下面是可以指定的内置控件:
Button、CheckBox、ComboBox、DateField、Image、Label、NumericStepper、Text(默认)、TextArea、TextInput

创建MXML的项目呈现器以显示商品的图片和名称
通过<s:MXItemRenderer>为DataGrid创建项目呈现器

创建内联的MXML项目呈现器用于显示Remove按钮
创建项目呈现器的另一方式是使用<mx:itemRenderer>标签
该标签允许在DataGridColumn中以内联的方式声明并创建项目呈现器
在<mx:cellRenderer>标签中,放置一个<fx:Component>标签,这样标签内部将拥有自己的区域
可以在其中进行导入,函数定义等。
注意:内联项目呈现器仅特定用一个DataGrid,无法在其它DataGrid中重用!
--------------------------------------------------------------------
1.使用DataGrid列出购物车中所有的商品
ShoppingView.mxml
<?xml version="1.0" encoding="utf-8"?>
<s:Group xmlns:fx="http://ns.adobe.com/mxml/2009" 
		 xmlns:s="library://ns.adobe.com/flex/spark" 
		 xmlns:mx="library://ns.adobe.com/flex/mx" width="0" height="0" xmlns:components="components.*">
	<s:layout>
		<s:HorizontalLayout/>
	</s:layout>
	<s:states>
		<s:State name="State1"/>
		<s:State name="cartView"/>
	</s:states>
	

	<fx:Script>
		<![CDATA[
			import cart.ShoppingCart;
			import cart.ShoppingCartItem;
			
			import components.ProductItem;
			
			import events.ProductEvent;
			
			import mx.collections.ArrayCollection;
			
			import valueObjects.Product;
			[Bindable]
			public var shoppingCart:ShoppingCart = new ShoppingCart();//创建一个购物车,每种商品都使用同一个购物车!
			[Bindable]
			public var groceryInventory:ArrayCollection;//用于存放HTTPService返回的各种商品信息
			
			//查看当前购物车中的商品
			private function handleViewCartClick( event:MouseEvent ):void {
				this.currentState="cartView";
			}
			
			//该方法返回一个字符串,用来作为数据集的呈现方式,由labelFunction函数指定
			//当List中使用labelFunction时,会自动以正确的方式从dataProvider中获取数据并传递到该方法中
			//返回的字符串将作为被呈现的内容
			private function renderProductName(item:ShoppingCartItem):String {
				var product:Product = item.product;
				return "("+item.quantity+")" + product.prodName + " $" + item.subtotal;
			}
			
			
			//对ProductItem派发的addProduct事件进行监听并处理
			public function addProductHandler(event:ProductEvent):void {
				var sci:ShoppingCartItem = new ShoppingCartItem(event.product);//从自定义事件中获取属性
				shoppingCart.addItem(sci);
			}
			
			//对ProductItem派发的removeProduct事件进行监听并处理
			public function removeProductHandler(event:ProductEvent):void {
				var sci:ShoppingCartItem = new ShoppingCartItem(event.product);//从自定义事件中获取属性
				shoppingCart.removeItem(sci);
			}
		]]>
	</fx:Script>
	
	<fx:Declarations>
		<!-- 将非可视元素(例如服务、值对象)放在此处 -->
	</fx:Declarations>
	
	<!-- 该DataGroup被下面的ProductList取代  
	            通过事件冒泡实现商品的添加与删除
	            因为原来在ProductItem中直接对购物车添加或删除商品的操作无法进行
	  	  原因是无法对每个ProductItem都传入同一个购物车
		 [虽然this.parent.parent.shoppingCart可以访问到购物车,但是依赖性太强,不推荐]
		<s:DataGroup width="100%" height="100%" 
					 width.cartView="0" height.cartView="0" visible.cartView="false"
					 dataProvider="{groceryInventory}"
					 itemRenderer="components.ProductItem">
			<s:layout>
				<s:VerticalLayout/>
			</s:layout>
		</s:DataGroup>
	-->
	
	<!-- 使用具有事件监听出派发功能的组件替代原来的DataGroup-->
	<!-- 实现添加/删除商品的步骤:
	     ProductList作为一个组件,通过dataProvider获取到数据
		  在ProductList中又指名了itemRenderer为ProductItem
		  这样,ProductItem中的product属性就可以被赋予值
		  当添加商品的时候,会触发addProduct事件,而且事件可以冒泡
		  在ProductList中对该事件进行了声明,则可以对该事件继续向上冒泡
		  这样,在ShoppingView中就可以对这个事件进行捕获并处理!!!
	           然后,在ProductList组件中就可以指定事件发生后的处理函数了!!!
	-->
	<components:ProductList width="100%" height="100%"
							width.cartView="0" height.cartView="0" visible.cartView="false"
							dataProvider="{groceryInventory}"
							addProduct="addProductHandler(event)"
							removeProduct="removeProductHandler(event)"/>
	
	<!-- 购物车组件 -->
	<s:VGroup id="cartGroup" height="100%"  width.cartView="100%">
		<s:List id="cartList"
				dataProvider="{shoppingCart.items}" includeIn="State1"
				labelFunction="renderProductName"/>			
		<s:Label text="Your Cart Total: ${shoppingCart.total}"/>
		<s:Button label="View Cart" click="handleViewCartClick( event )" includeIn="State1"/>
		
		<!-- 使用自定义的DataGrid呈现购物车的详细信息-->
		<components:CartGrid id="dgCart" includeIn="cartView" width="100%" height="100%"
							 dataProvider="{shoppingCart.items}"
							 removeProduct="removeProductHandler(event)"/>
		
		<s:Button includeIn="cartView" label="Continue Shopping" click="this.currentState=''"/>
	</s:VGroup>
</s:Group>

2.DataGrid中的列单元格使用项目呈现器,单元格内显示图片和商品名称
自定义项目呈现器ProductName.mxml
<?xml version="1.0" encoding="utf-8"?>
<!--定义DataGrid中特定单元格的布局
    这里将在单元格中显示商品的图片和名称,而不只是字符串-->
<s:MXItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009" 
				  xmlns:s="library://ns.adobe.com/flex/spark" 
				  xmlns:mx="library://ns.adobe.com/flex/mx"
				  clipAndEnableScrolling="true"> <!-- 防止项目呈现器中的内容不超过其边界-->
	<s:layout>
		<s:HorizontalLayout/>
	</s:layout>
	<fx:Script>
		<![CDATA[
			import valueObjects.Product;
		]]>
	</fx:Script>
	
	<!-- data代表该行本身的数据, 所以可以通过data获取到product-->
	<s:Image source="assets/{(data.product as Product).imageName}" width="100%"/>
	
	<s:Label text="{(data.product as Product).prodName}" width="100%" height="100%"/>
</s:MXItemRenderer>

3.单元格中加入remove的button
DataGrid中通过内联引入项目呈现器,将一个button放到单元格中
实现购物车中商品的移除
移除商品的时候使用到了自定义的ProductEvent事件
在ShoppingView中对事件进行监听并处理
CartGrid.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:DataGrid xmlns:fx="http://ns.adobe.com/mxml/2009" 
			xmlns:s="library://ns.adobe.com/flex/spark" 
			xmlns:mx="library://ns.adobe.com/flex/mx"
			editable="true"
			variableRowHeight="true"> <!-- 全局设置为可编辑,flex会根据缩略图自动调整DataGrid的行高-->
	<fx:Declarations>
		<!-- 将非可视元素(例如服务、值对象)放在此处 -->
	</fx:Declarations>
	
	<fx:Metadata>
		[Event(name="removeProduct", type="events.ProductEvent")]
	</fx:Metadata>
	
	<fx:Script>
		<![CDATA[
			import cart.ShoppingCartItem;
			private function renderPriceLabel(item:ShoppingCartItem,column:DataGridColumn):String {
				var subtotal:Number = item[column.dataField];//通过列名从item中获取数据
				return "$"+String(subtotal);
			}
		]]>
	</fx:Script>
	
	
	<mx:columns>
		<mx:DataGridColumn headerText="Product" dataField="product" editable="false"
						   itemRenderer="components.ProductName"/> <!-- 不可编辑,并且使用自定义项目呈现器来进行数据呈现-->
		
		<!--itemEditor指定编辑数据时使用的编辑器  editorDataField指定了对应的属性--> 
		<mx:DataGridColumn headerText="Quantity" dataField="quantity"
						   itemEditor="mx.controls.NumericStepper"
						   editorDataField="value"/>
		
		<mx:DataGridColumn headerText="Amount" dataField="subtotal" editable="false"
						   labelFunction="renderPriceLabel"/> <!-- 不可编辑,通过labelFunction指定了一个函数来对呈现的数据进行操作-->
		
		<mx:DataGridColumn editable="false">
			
			<!-- 创建内联项目呈现器-->
			<mx:itemRenderer>
				<fx:Component>
					<s:MXItemRenderer>
						<s:layout>
							<s:VerticalLayout horizontalAlign="center"/>
						</s:layout>
						<fx:Script>
							<![CDATA[
								import cart.ShoppingCartItem;
								
								import events.ProductEvent;
								private function removeItem(item:ShoppingCartItem):void {
									var prodEvent:ProductEvent = new ProductEvent("removeProduct",item.product);
									dispatchEvent(prodEvent);
								}
							]]>
						</fx:Script>
						<s:Button label="Remove" click="removeItem(data as ShoppingCartItem)"/>
					</s:MXItemRenderer>
				</fx:Component>
			</mx:itemRenderer>
			
		</mx:DataGridColumn> <!-- 不可编辑-->
	</mx:columns>
</mx:DataGrid>


分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics