在使用Flex组件时,我们常常会遇到复杂组件要求。如:对DataGrid加一列全选、或对DataGrid加一列图表、改变DataGrid的表头为一张图片等。此时,Flex为我们提供的组件已经不能满足我们的需求,我们需要使用内联组件ItemRenderer去自定义一些功能。下面我们使用一个例子演示使用ItemRenderer给DataGrid的一个Column嵌入linkButton,点击触发linkButton的方法:
1、假如我们有如下一个DataGrid:
<dc:SuperDataGrid width="100%" height="100%" dataProvider="{citedList}" columnsEnable="true"> <dc:columns> <mx:DataGridColumn dataField="regNum" headerText="注册号"/> <mx:DataGridColumn dataField="tmName" headerText="商标名称"/> <mx:DataGridColumn dataField="intCls" headerText="类号" width="60"/> <mx:DataGridColumn headerText="操作"/> </dc:columns> </dc:SuperDataGrid>
效果为:
2、我们试图在“操作”列的每一行嵌入一个名为“取消引证”linkButton,点击删除此引证商标。
简单的ItemRenderer嵌入(主要指没有复杂的事件监听、回调、参数传递)可以用类似于如下代码实现:
<mx:DataGridColumn headerText="操作" itemRenderer="com.dc.business.xxxx.xxxx.MyRnder"/> <mx:DataGridColumn headerText="操作" itemRenderer="{new ClassFactory(com.dc.business.xxxx.xxxx.MyRnder)}"/>
而此例中,我们的需求相对上面的方式比较复杂, 主要是内嵌组件需要执行外部组件传递的方法。这种场合我们需要新建一个IFactory的实现类(Flex4的ItemRenderer接受IFactory工厂来创建Renderer):
package com.xxx.xxx.xxx { import mx.core.IFactory; public class MyItemRenderIFactory implements IFactory { //点击linkbutton的回调函数 private var linkButtonCallbackFun:Function = null; //构造方法,传入单击的回调函数 public function MyItemRenderIFactory(fun:Function){ super(); this.linkButtonCallbackFun = fun; } //实现IFactory接口中的方法,即此工厂创建对象的方法 public function newInstance():*{ //创建对象 var render:MyRender = new MyRender(); render.setClickCallbackFun(linkButtonCallbackFun); //返回对象 return render; } } }
3、新建MXDataGridItemRenderer的MyRender.mxml定义一个linkButton,同时注册点击事件为传进来的clickCallFuncion(逻辑写死也行,但是传进来更通用,易于拓展)
其中data是内置对象,可以拿到当前这一行的数据源。dataGridListData也是内置对象,可以获取当前这个frig列的信息。
<?xml version="1.0" encoding="utf-8"?> <s:MXDataGridItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" focusEnabled="true" xmlns:dc="http://digitalchina.dc.tm"> <!--<s:Label id="lblData" top="0" left="0" right="0" bottom="0" text="{dataGridListData.label}" />--> <fx:Script> <![CDATA[ private var clickCallbackFun:Function; /** * func:Function 回调函数 * 此方法将会在Factory中调用 */ public function setClickCallbackFun(func:Function):void{ this.clickCallBackFun=func; }/** * 单击事件,使用工厂构造此Render时传进来的clickCallBackFun * */ protected function clickHandler(event:MouseEvent):void { if(this.clickCallBackFun!=null){ this.clickCallBackFun.call(this,data.regNum,data.intCls); } } ]]> </fx:Script> <dc:LinkButton label="取消引证" styleName="linkedLabel" click="clickHandler(event)"/> </s:MXDataGridItemRenderer>
4、改造我们最初的DataGrid,绑定ItemRenderer工厂:
[Bindable] public var linkButtonIFactory:MyItemRenderIFactory = new MyItemRenderIFactory(cite); ...略... //linkButton的单击事件,业务逻辑处理 public function delCite(regNum:String, intCls:String):void{ BaseService.asyncInvoke('tmzrAction','deleteTmCite','TMZR',activCode, currentAppObj.appNum, regNum, intCls).addResultListener(function(event:ResultEvent):void{ var eachCited:* = null; for(var i:int = 0; i < citedList.length; i++){ eachCited = citedList.getItemAt(i); if(regNum == eachCited.regNum && intCls == eachCited.intCls){ citedList.removeItemAt(i); break; } } }); } ...略... <dc:GroupBox title="相同近似引证商标" id="xtjslb" width="100%" height="50%" imageName="icon_dot_01.png"> <dc:SuperDataGrid width="100%" height="100%" dataProvider="{citedList}" columnsEnable="true"> <dc:columns> <mx:DataGridColumn dataField="regNum" headerText="注册号"/> <mx:DataGridColumn dataField="tmName" headerText="商标名称"/> <mx:DataGridColumn dataField="intCls" headerText="类号" width="60"/> <mx:DataGridColumn headerText="操作" dataField="regNum" itemRenderer="{linkButtonIFactory}"/> </dc:columns> </dc:SuperDataGrid> </dc:GroupBox>
最终效果:
拓展:
列头部内嵌使用column的headerRenderer属性。将headerRenderer、column的itemRenderer同时嵌入checkbox,则可以将dataGrid的一个column对象封装成全选效果。效果如下所示: