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.*;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值