首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 媒体动画 > flex >

Flex初记

2012-11-23 
Flex小记1. DataGrid中可编辑的Column,获取编辑前的值和编辑后的值: ?? DataGrid iddg dataProvidor

Flex小记

1. DataGrid中可编辑的Column,获取编辑前的值和编辑后的值:
?? <DataGrid id="dg" dataProvidor="{userVOs}" editable="true" itemEditEnd="updateUserVOHandler(event)">
?????? <mx:DataGridColumn id="serialId" headerText=" " width="30" sortable="false"
??????????????????????????????????? editable="false"/>
?????? <mx:DataGridColumn dataField="userName" headerText="用户名" editable="true"/>
?????? <mx:DataGridColumn id="descColumn" dataField="attachmentDescription"?? headerText="用户描述" editable="false"/>
?????? <mx:DataGridColumn headerText="部门" dataField="department" editorDataField="value" id="depart" editable="true" >??
??????????? <mx:itemEditor>??
??????????????? <mx:Component>??
??????????????????????? <mx:ComboBox editable="true" width="100">??
??????????????????????????? <mx:dataProvider>??
??????????????????????????????? <mx:String>A部门</mx:String>??
??????????????????????????????? <mx:String>B部门</mx:String>??
??????????????????????????????? <mx:String>C部门</mx:String>????
??????????????????????????? </mx:dataProvider>??
??????????????????????? </mx:ComboBox>??
??????????????? </mx:Component>??
??????????? </mx:itemEditor>??
??????????? </mx:DataGridColumn>
?? </DataGrid>
??? <mx:Script>
??????? <![CDATA[
??????? public function updateUserVOHandler(event : DataGridEvent) : void
??????? {
????????? if (event.dataField == "userName")
????????? {
????????????? var preUsername : String = event.itemRenderer.data.userName; // 编辑前该Cell的数据,不过在下一步获取了当前值之后,更改为编辑后的值,所以要处理编辑前的值,需要在下一步之前;
????????????? var currentUserName : String = event.currentTarget.itemEditorInstance.text; // 因为该UserName Column是普通的TextInput文本格式,所以event.currentTarget.itemEditorInstance获得的是TextInput,所以通过其text属性来获取编辑后的值;如果是采用其他格式的Column,则需要获取对应的属性的值,比如是Combox的Column,则获取selectedLabel属性,请看下面的判断;另外可以通过下面的形式去获取编辑后的值:
????????? //dg.itemEditorInstance[DataGridColumn(dg.columns[event.columnIndex]).editorDataField];
????????? }
????????? if (event.dataField == "department") // 获取绑定字段名称
????????? {
????????????? var newDepart : String = "";
????????????? try{?
??????????????????????? newDepart = ComboBox (event.currentTarget.itemEditorInstance).selectedLabel//获取编辑后的新值?
??????????????????? }catch(errObject:Error){?
???????????????????????? Alert.show(errObject.toString());
??????????????????? }?
????????? }
????????? // 省略 调用RemoteObject实现与后台通信
??????? }
??? ]]>
??? </mx:Script>
?? 其中,使用editable和itemEditEnd属性来处理可编辑的单元,使用下面的
??

2.对于MXML中的DataGrid,如果修改其中一个DataGridColumn,则可以使用ValueObjectUtil类中的updateAttributes来更新并且及时刷新此DataGrideColumn在页面上的显示,例如ValueObjectUtil.updateAttributes(aDataGrid.selectedItem, userVO),既是将userVO的值更新aDataGrid.selectedItem;

3. Flex中对于浮点数的计算,会出现精度丢失的问题,因为计算机实现浮点数计算的方式本来就会出现精度丢失;为了得到精确的浮点数操作,可以使用先乘以一个基数,再除以同一个基数的方式去避免精度丢失,即放大操作数,操作结束然后缩小操作数,但是切记,给出的基数的位数要超过计算的数据中最大的小数位数:
?? var fixed : Number = 100;
?? var d1 : Number = 1.1;
?? var d2 : Number = 1.23;
?? var d3 : Number = d1 + d2; //这样计算下来,得到的d3结果类似: 2.29999999;
?? var d4 : Number = (d1 * fixed + d2 * fixed) / fixed; //d4的结果是精确的: 2.3
?? 如上所示,计算数据的最大小数位数是2位(1.23),则fixed至少是百位数;

?? 如果只需要采用四舍五入的方式,就可以使用Number的toFixed(int 小数点位数scale)方法来获取scale位小数的四舍五入数据;

?

4. Tree的逐级加载数据,具体用法:

????a. 重写tree实例的dataDescriptor属性对应的类, 定制的dataDescriptor需集成DefaultDataDescriptor;

??? b. 必须重写getChildren方法,返回一个实现了ICollectionView的集合,比如ArrayCollection,该集合将作为tree中点击的node的children展示出来;

??? c. 必须重写isBranch方法,判断点击的node是否是叶子节点(没有children),返回boolean;

??? d. 可在定制的dataDescriptor类中重写hasChildren方法,用以判断是否需要加载children,此非必须;

??? 以上重写方法可在DefaultDataDescriptor类中找到;


? 5. Flex中各种图的使用,其实有一些基本的东西,只要把握住了,大同小异:

????? a. horizontalAxis用来定义常用ColumnChart, BarChart等图的x轴,如

?????????? <mx:horizontalAxis>
??????????????????????????? <mx:CategoryAxis categoryField="name" title="姓名"/>
???????????</mx:horizontalAxis>

?????????? 其中采用CategoryAxis定义x轴按照chart的dataprovider集合的name属性分类排列;CategoryAxis的dataFunction属性指定一个方法,其返回值应可用作当前项目的 categoryValue。如果设置了此属性,则自定义数据函数的返回值优先于categoryField;

????? b. verticalAxis可以重新定义y轴

????????????<mx:verticalAxis>
??????????????????????????? <mx:LinearAxis interval="1" minimum="1"/>
??????????? </mx:verticalAxis>

????? c. series中可以定义很多展示方式,比如柱(ColumnSeries)、线(LineSeries)、点(PlotSeries),如果x轴省略,则默认为horizontalAxis中的CategoryAxis的dataFunction或者categoryField;

????????? <mx:series>
??????????????????????????? <mx:ColumnSeries yField="score" displayName="成绩"/>
??????????????????????????? <mx:LineSeries yField="average" form="curve" displayName="平均分"/>

??????????????????????????? <mx:PlotSeries yField="ranking" displayName="排名"/>

????????? </mx:series>

???? d. Legend用以向图表中添加图例,此图例可为图表中的每个数据系列显示一个标签,以及一个用于显示系列的图表元素的键,id指向chart即可;

?????????? <mx:Legend id="userChart">

???? c. 雷达图RadarChart稍微复杂一些,但是原理一样,它的每个角就是dataProvider集合中的一个对象,需要导入ilog-elixir.swc和ilog-elixir_rb.swc包:

???????? 其中angularAxis属性的categoryField或者dataFunction属性就是定义每个角的显示名,并且成为以后添加到此雷达图的series的x轴显示名;

???????? 要添加series到雷达图中,首先new RadarLineSeries,然后定义好line的displayName,dataField属性,其中dataField属性应该对应到雷达图dataProvider中每个Object中对应的属性;然后push new line到雷达图的series中;

???????? 可能比较难以理解,给点例子吧:

???????? mxml:

???????? <ilog:RadarChart id="demoRadar" showDataTips="true" columnWidthRatio="0.8" width="100%" ?height="100%" dataProvider="{gatherVOs}" series="{radarSeries}">
??????????????????<ilog:angularAxis>
?????????????????????? <ilog:AngularAxis categoryField="name"/>
????????????????? </ilog:angularAxis>

????????? </ilog:RadarChart>

?

????????其中,gatherVOs其实是一个临时造出来的集合,它里面的Object的属性,比如itemName和各个部门Id所作为的属性都是临时的,而之所以要用部门Id来做gatherVOs中Object的属性,是为了显示数据的方便性,在添加部门line时,它能够自动对应起来;

?

??????????as:

??????????protected function initRadarData() : void
??????????? {

??????????????? createGatherVOItems(Constant.RUGLAR_ARR, departmentVOs.source, gatherVOs);

??????????????? averageLine = new RadarLineSeries();
??????????????? averageLine.displayName = "组内平均分";
??????????????? averageLine.dataField = Constant.GOURP_AVERAGE_AVG;

??????????????? radarSeries.push(averageLine);

??????????????? demoRadar.series = radarSeries;

????????????? }

?

????????????? //创建要展示的数据,让它们放在雷达图的dataProvider的集合中

???????????? private function createGatherVOItems(checkupItemNames : Array, source : Array, target : ArrayCollection) : void
??????????? {
??????????????? for (var i = 0; i < checkupItemNames.length; i++)
??????????????? {
??????????????????? var gatherVO : Object = new Object();
??????????????????? gatherVO.itemName = checkupItemNames[i];
??????????????????? for each (var departmentVO : DepartmentVO in departmentVOs.source)
??????????????????? {
??????????????????????? gatherVO[departmentVO.id] = i;?// i 是任意给的,无实际意义
??????????????????? }
??????????????????? gatherVO[Constant.AVERAGE_AVG] = 50 - i;? // 50-i 是任意给的,无实际意义
??????????????????? target.addItem(gatherVO);
??????????????? }
??????????? }

?????

?????????? //点击部门DataGrid,将点击的部门按照line形式添加到雷达图

??????????? override protected function departDgClickHandler() : void???
??????????? {
????????????????var departLine : RadarSeries = new RadarLineSeries();
??????????????? departLine.displayName = departmentDg.selectedItem.departName;
??????????????? departLine.dataField = departmentDg.selectedItem.id.toString();
??????????????? series.push(departLine);
??????????????? demoRadar.series = radarSeries;
???????????? }

?

?????????? //常量数据:

??????????? Constant.RUGLAR_ARR = ['履行职责与转变职能?', '服务质量与工作效率?', '工作实绩与社会效果?',
??????????? '依法行政与政务公开', '公正廉洁', '开展“创先争优”活动情况'];

????????????AVERAGE_FIELD_NAME = "averageField";

??????????

??????????? 效果参考附件中 radar.jpg

?

6. Flex支持以RPC(Remote Procedure Call,远程调用)方式和外部系统交互数据,RPC服务器端可以是一个网页程序,WebService(网络服务),服务端对象等;其中,Flex常用的客户端RPC工具有HttpService, WebService和RemoteObject,RPC通信是一个异步通信的过程,客户端把数据请求发送给服务端,然后等待服务端把结果返回到客户端;

???? 下面简介一下我对这些工具或者说协议的理解:

????a. HttpService,在mx.rpc.http包中,它主要发送HTTP形式的Get和Post请求,Get和Post请求的区别在于,Get请求的参数数据是可见的,并且对请求传输的数据大小有限制,而Post请求是将参数数据打包在数据包中传输到服务端,在服务端被自动解析成服务端的变量,所以在包含了敏感数据时,可将Flex中HttpService的method设置为Post;

?????? 它请求的地址是可是一个服务端的页面,也可以是xml页面;如果包含参数,可以采用mxml的<mx:request>对象,也可以使用ActionScript的一个包含请求参数的Object对象,然后在send方法中使用该对象,即xxService.send(object;还可以使用xml数据作为参数对象,其中HttpService的contentType要设定为"appliction/xml";采用xml数据,1是可以处理结构比较复杂的数据,2是xml格式符合web标准,所有的服务端语言都能够方便的解析,使得程序具有良好的移植性;

?????? 所有的工具或者协议在接收返回的数据时,都会被触发result事件,如果出错了,就会触发fault事件,fault的rootCause对象可以判断具体的错误;

?????? 不管返回的数据是什么形式,都会被HttpService解析成Object类型,即便是xml格式的数据,也会被解析成一个树形结构的对象,因为HttpService默认返回的是object类型数据;如果想得到其他类型的数据,可以修改resultFormat属性,比如要将数据以xml对象类型返回,则可使用e4x语法解析;所以由于HttpService具有自动解析xml文件的功能,使得它读取xml文件非常便捷,省去了编写解析代码的步骤;返回数据时触发的ResultEvent事件中,event.result代表返回的数据对象;另外,xxxService.send()操作属于一个AsyncToken对象,这样的话,event.token中result的数据等同于event.result数据;showBusyCursor属性可是在send方法请求后数据请求未完成前将鼠标设置为繁忙状态;

?????? b. WebService位于mx.rpc.soap包中,它和HttpService相似,也采用HTTP协议来进行通信,但是原理却截然不同;Web Service是网络应用程序的标准,在用户的角度来看,它就是一个应用程序,它向外界暴露出能投通过Web进行调用的API集合,用户直接调用这些API来实现某些功能;因为它定义了如果在Web上实现互操作性,所以只要符合标准,开发者可以使用任何语言、任何平台上开发它;为了保证数据的跨平台传输,它采用了符合web标准的XML来描述数据,它采用WSDL(Web Service Define Language)来描述WebService相关的信息及其函数、参数和返回值,WSDL使用了XML语法,并且制定了严格的格式;

?????????? WebService中的wsdl属性比较设定,而且它比HttpService多了一个<mx:operation>属性,表示要调用的函数,name是函数名,其中的<mx:request>同样传递的是函数参数;建立了webservice请求后,同样通过调用send方法来执行请求动作,必须要指定函数名(目标函数),如:ws.getNews.send();

?????????? ws返回的数据类型,即使是xml数据,也返回字符串类型,所以不需要设定数据格式;

?????????? 也可以在ActionScript中定义WS,然后对要请求的目标函数进行result时间注册,然后ws进行loadWSDL操作,当发送请求时,直接调用ws的目标函数,并且可以设置参数,就像调用本地函数一样,如:

?????????? var ws : WebService = new WebService();

?????????? ws.getNews.addEventListener("result", resultHandler);

???????????ws.loadWSDL("xxx.asmx?.wsdl");

?????????? ws.getNews(a, b, c);

?

?????? c. Remoting(Remote Object),因为HttpService和WebService都只支持文本格式的数据通信,在数据小的时候,这样方式比较合适,但是如果要传输复杂的数据,就必须先转换为其他文本格式供Flex调用,比如xml,而Flex还得把转换的xml数据还原成原来的复杂的数据结构,这样服务端和客户端都多了一道工序,降低了运行效率;从而Flex可以采用Remoting技术,Remoting采用AMF(Action Message Format)进制数信息格式传递数据,AMF是Adobe独家开发出来的通信协议,采用二进制压缩,支持数据的序列化和反序列化,为SWF文件与Remoting服务端通信提供了一种轻量级的高效能的通信方式;AMF最大的特色在于它可以直接将Flash Player的内置对象,比如Object,Array,Date,XML等复杂的数据结构直接传回服务器端,并且在服务器端自动解析为适合的对象,节约了开发时间;由于它采用高度压缩数据,因此非常适合用来传输大量的数据,数据越大,它的传输效益就越高,远远超过以上两种方式;

?????? 在使用Remoting时,数据在客户端和服务端的传递进行了两次大的转换,首先是客户端向服务器发送数据,ActionScript的数据类型转换为AMF格式;服务器端接收到数据,转换为服务端数据,然后返回数据,客户端收到,将AMF格式转换为ActionScript的数据类型;即在通信过程中,数据在传输中会被自动转换为AMF格式数据,在客户端和服务端会被转换为各自可处理的数据类型,比如在Flex客户端的ActionScript类型:Object, Array, XML;

?

7. 使用<mx:lineSeries>图标时,当鼠标悬停在改线时,会出现小圆点,如果想一直保持该系列点,可以使用itemRenderer来实现,如下:

????增加lineSeries属性itemRenderer="mx.charts.renderers.CircleItemRenderer",并且导入import mx.charts.renderers.*;

热点排行