Flex4.5中DataGrid组件的使用
有关Flex的DataGrid文章的确不少,都是零零碎碎的,目前还没有发现有个完整的例子供网友参考,这次我花了两天时间做了下Flex关于DataGrid一个指标数据管理系统,当然设计到的mxml会很多,大都是与DataGrid相关,我就抽取最常用的DataGrid的增删改同步数据库及页面数据来讲解
首先整理下思路,首先无论是删除还是修改,必须得获取当前行所在的记录,那么可以设置个全局变量,当DataGrid的itemClick事件出发时将选中的行赋给全局变量
[Bindable]public var acItemsSelected:Object;;
//事件方法
protected function myGrid_itemClickHandler(event:ListEvent):void
{
acItemsSelected = myGrid.selectedItem;
}
这样的话就可以获得了当前选中的对象了
如果删除和修改的话,通常传到后台的肯定含有对象的ID项,那么这个ID是怎么获取的呢,通过acItemsSelected.xxxId能获取,那么这个xxxId必须是在DataGrid中有,设置为不显示就好了,例如我就是这么做的
<mx:DataGridColumn visible="false" dataField="targetCalId" />
这样的话,要更改的数据等都能通过ID传到后台查询相应对象更改删除了,接下来的事是比较重要的,如果光删除数据库是不行的,页面数据也要保持同步,关于dataGrid也没有好的刷新方法,所以你上网一搜,可能有的人会告诉你对于删除这样做:dataArray.removeItemAt(myGrid.selectedIndex);
增加这样做:dataArray.addItemAt(obj,0);
修改这样做:dataArray.setItemAt(obj,myGrid.selectedIndex);
这里说的dataArray是指的是DataGrid的DataProvider的值集合【当然肯定得声明称全局变量】
这样的写法呢可能你觉得,哎,是对的,其实不然,这并没有真正起到作用,对于FLEX来说缓存是相当大的,不行的话你通过这个修改行记录的属性后,再点这行记录的属性编辑页面发现值根本没改,所以所没有进行二次查询数据库了,利用的是缓存。即便是你调用了初始化查询数据库的那个方法,也是不行的,还是有缓存,最好的做法就是,抛弃上面的三种写法,只需要两步就可以实现刷新,第一初始化DataGrid的那个方法请求必须是URLRequest的,添加一个参数类似于
var u:URLVariables=new URLVariables("temp="+Math.random());
当然不一定非要是temp什么名字都行,然后在返回操作成功提示后调用这个初始化方法,你会发现真的起作用了。
其实建议关于URLRequest传参数的最好带上这个参数,也不费事,可以在很多场合下解决缓存不更新问题



state语法的改变

state语法变了,变得更加的有弹性和直接。你甚至可以根据上下文来针对性的改变你的状态。下面是重点:

1,只有状态被定义到了状态数组。

2,AddChild和RemoveChild,不能再用了。取而代之的是includeIn和excludeFrme属性 。这两个属性是组件的属性。

看例子吧!

这是flex3应用状态的方式。



<mx:states><mx:State name="submitState" basedOn="">
<mx:AddChild relativeTo="{loginForm}" >
<mx:Button label="submit" bottom="10" right="10"/>
</mx:AddChild>
<mx:RemoveChild target="{firstTextInput}"/>
</mx:State>
</mx:states>
<mx:TextInput id="firstTextInput" />
<mx:Canvas id="loginForm" />


这是flex4
<s:states>
<s:State name="submitState" />
</s:states>
<s:TextInput id="firstTextInput" excludeFrom="submitState" />
<s:Group id="loginForm" >
<s:Button label="submit" bottom="10" right="10" includeIn="submitState"/> </s:Group> 3,setProperty,setStyle和setEvent被点语法取代了。

下面是flex3的做法

<mx:states>
<mx:State name="submitState" basedOn="">
<mx:SetProperty target="{submitButton}" name="label" value="submit" />
<mx:SetStyle target="{submitButton}" name="textDecoration" value="underline"/>
<mx:SetEventHandler target="{submitButton}" name="click" handler="trace('done');"/>
</mx:State>
<mx:State name="clearState" basedOn="">
<mx:SetProperty target="{submitButton}" name="label" value="clear" />
<mx:SetEventHandler target="{submitButton}" name="click" handler="emptyDocument()" />
</mx:State>
</mx:states>
<mx:Button id="submitButton" />


下面是flex4的做法
<s:states>
<s:State name="submitState" />
<s:State name="clearState" />
</s:states>
<s:Button label.submitState="submit" textDecoration.submitState="underline"
click.submitState="trace('done')" click.clearState="emptyDocument()" label.clearState="clear" textDecoration.clearState="none"/> 4,组件不能在无状态或空的状态。它默认的状态时第一个声明的状态。


Flex 3.x到Flex 4.5 容器与布局组件
容器(Container)
在说布局之前,我们先说说Flex4中得容器的变化。Flex4中提供了一些新的容器,并且不在推荐使用Flex3中的容器了。
Group (包括HGroup、VGroup、TileGroup) 与DataGroup
SkinnableContainer、SkinnableDataContainer、Panel、TitleWindow、NavigatorContent、BorderContainer, 和Application(Panel、TitleWindow、NavigatorContent以及BorderContainer都是SkinnableContainer的子类)
当然Spark容器都具有以下特点:
可变的布局:除了部分已经自定义布局的容器(如HGroup、VGroup、TileGroup)的布局不能改变,其他的Spark容易都可以改变其布局,在本节后面做详细介绍Spark布局;
皮肤:我们知道Spark容器的皮肤和Flex3中的皮肤已经有很大的不同了,大部分的Spark容器都支持皮肤,当然这些容器得继承SkinnableContainer或者SkinnableDataContainer;但是为了提高性能及减小应用的大小,不是所有的容器都支持皮肤,如果容器没有继承自这两个Skinable类之一,那么他就不支持皮肤,如Group、DataGroup;
添加的子控件(Element/Child):DisplayObject、UIcomponent、Container、IVisualElement、IGraphicElement、IVisualElementContainer、ISharedDisplayObject。这几个类型,有些是在Spark中引入的新的类型,在后面我将详细的说一说他们的作用以及之间的关系,包括和Flex3 Halo之间的联系等。【传送门待添加】
下面列出一些Flex官方推荐的与Flex3的容器的映射关系,但是我们用的时候却不一定需要按照这个来:
Flex 3 Flex 4 (Spark)官方建议 实际应用备选建议
mx.containers.Canvas spark.components.BorderContainer spark.components.Group
mx.containers.Box spark.components.BorderContainer spark.components.Group
mx.containers.HBox spark.components.BorderContainer spark.components.HGroup
mx.containers.VBox spark.components.BorderContainer spark.components.VGroup
mx.containers.Panel spark.components.Panel spark.components.Panel
mx.containers.Tile spark.components.BorderContainer spark.components.Group(使用TileLayout)
mx.containers.TitleWindow spark.components.TitleWindow spark.components.TitleWindow
mx.containers.Form spark.components.Form spark.components.Form
上面的表格中有很多地方都可以用BorderContainer或者是Group,是不是感到困惑呢?从前面的一段话中可以看出,Group是没有Skin的,BorderContainer是有Skin的,所以在使用的时候可以根据自己的需求,由于Layout已经可以自己设定,那么只需要看是否使用Skin,就可以决定究竟是使用BorderContainer还是Group。另外还有很多具体的变化,从Flex3刚转到Flex4,可能知道上面的对应关系还不够,还有很多细节,如clipping、scrollbar等问题,我会在讲解Skin的一篇说说clipping、scrollable以及如何给自定义Container。
布局(Layout)
Flex4/Spark组件架构的新功能之一是可以定制一个容器的布局而不必改变容器本身,正如前面提到的“可变的布局”,默认的有BasicLayout、HorizontalLayout、TileLayout、VerticalLayout四大布局方式。
基本布局
BasicLayout:这是spark组件默认的布局方式,即绝对定位布局。在FlexSDK3里面对应的是:layout=”absolute”;类似Flex3中的Canvas的布局;
HorizontalLayout:这是spark组件库里面的水平布局方式。在里面对应的是:layout=”horizontal”;对应Flex3中得HBox的布局方式;
VerticalLayout:这是spark组件库里面的竖直布局方式。在FlexSDK3里面对应的是:layout=”vertical”;对应Flex3中得VBox的布局;
TileLayout:这是spark组件库新增的布局方式,即格子布局方式。TileLayout布局方式可以说是HorizontalLayout和VerticalLayout结合的方式;当然可以看出这就是Flex3中得Tile组件的布局方式。
布局使用方法
我们仍然分别使用MXML和ActionScript两种方式来举例说明。首先来说最常用的方式,也就是MXML的方式:
<s:Group>
<s:layout>
<s:HorizontalLayout />
</s:layout>
</s:Group>
例子中用的是HorizontalLayout,当然,你可以使用其他的Layout。
<fx:Script>
<![CDATA[
import mx.core.LayoutDirection;
import mx.events.FlexEvent;
import spark.layouts.HorizontalLayout;
protected function creationCompleteHandler(event:FlexEvent):void {
group.layout = new HorizontalLayout;
//group.layoutDirection = LayoutDirection.LTR;
}
]]>
</fx:Script>
<s:Group layoutDirection="rtl">
<s:Button label="A" />
<s:Button label="B" />
</s:Group>
当然,在上面的代码中除了设置layout,还设置了layoutDirection,这是在4.1中加入的属性,用来指定布局方式是从左往右(ltr)还是从右向左(rtl),也可以像注视中的AS代码那样设置。
Layout的属性设置
另外,Flex3中,我们可以在Container上设置设置的与布局相关的属性现在都移到了layout上,比如verticalAlign、horizontalAlign、gap以及各个方向的padding值:
<s:Group layoutDirection="rtl">
<s:layout>
<s:HorizontalLayout verticalAlign="baseline" horizontalAlign="left" gap="5" paddingBottom="1" paddingLeft="1" paddingRight="1" paddingTop="1" />
</s:layout>
<s:Button label="A" />
<s:Button label="B" />
</s:Group>
对于这些属性基本与Flex3中得相同,只是现在是针对layout设置了。另外layout还有一些在Flex中没有见过的属性,我们特别说下面两个:clipAndEnableScrolling、useVirtualLayout,他们的设置方法和gap、padding之类的属性一样设置:
clipAndEnableScrolling: 如果是true,则将超出范围的children裁掉不显示出来,如Flex3中得Canvas等,如果显示的范围超出了Canvas的范围,则不会显示;如果是false,则不管他的children是否超出他的范围,都会完全显示出来(但不会超出Application的范围)。
Flex4中有两个地方可以设置这个属性,一个是Skin中(该属性是定义在GroupBase中的property,而Skin继承GroupBase),一个是Layout中,而默认情况GroupBase中的property也是由Layout中取出,如下贴出SDK中GroupBase.get clipAndEnableScrolling的代码:
public function get clipAndEnableScrolling():Boolean {
if (_layout) {
return _layout.clipAndEnableScrolling;
}
else if (_layoutProperties && _layoutProperties.clipAndEnableScrolling !== undefined)
{
return _layoutProperties.clipAndEnableScrolling;
}
else{
return false;
}
}
由此我们可以看出,该属性在layout中设置才是合情理的。
useVirtualLayout:顾名思义是虚拟布局,那么虚拟布局是什么概念呢?我想我还是从它的用途说起吧。如果你熟悉Flex3中List的ItemRenderer的渲染机制,那么我们就当作Flex3中的List就是useVirtualLayout的效果。啥意思呢?当开启useVirtualLayout(设为true)之后,并不是所有的children都会被渲染,而是只有当前能够显示出来的child才会被渲染(比如List只显示一些itemRenderer,其他的通过Scrollbar控制)。
显然,这样我们可以大幅度的提高效率。


Flex4.5中DataGrid组件的使用
有关Flex的DataGrid文章的确不少,都是零零碎碎的,目前还没有发现有个完整的例子供网友参考,这次我花了两天时间做了下Flex关于DataGrid一个指标数据管理系统,当然设计到的mxml会很多,大都是与DataGrid相关,我就抽取最常用的DataGrid的增删改同步数据库及页面数据来讲解
首先整理下思路,首先无论是删除还是修改,必须得获取当前行所在的记录,那么可以设置个全局变量,当DataGrid的itemClick事件出发时将选中的行赋给全局变量
[Bindable]public var acItemsSelected:Object;;
//事件方法
protected function myGrid_itemClickHandler(event:ListEvent):void
{
acItemsSelected = myGrid.selectedItem;
}
这样的话就可以获得了当前选中的对象了
如果删除和修改的话,通常传到后台的肯定含有对象的ID项,那么这个ID是怎么获取的呢,通过acItemsSelected.xxxId能获取,那么这个xxxId必须是在DataGrid中有,设置为不显示就好了,例如我就是这么做的
<mx:DataGridColumn visible="false" dataField="targetCalId" />
这样的话,要更改的数据等都能通过ID传到后台查询相应对象更改删除了,接下来的事是比较重要的,如果光删除数据库是不行的,页面数据也要保持同步,关于dataGrid也没有好的刷新方法,所以你上网一搜,可能有的人会告诉你对于删除这样做:dataArray.removeItemAt(myGrid.selectedIndex);
增加这样做:dataArray.addItemAt(obj,0);
修改这样做:dataArray.setItemAt(obj,myGrid.selectedIndex);
这里说的dataArray是指的是DataGrid的DataProvider的值集合【当然肯定得声明称全局变量】
这样的写法呢可能你觉得,哎,是对的,其实不然,这并没有真正起到作用,对于FLEX来说缓存是相当大的,不行的话你通过这个修改行记录的属性后,再点这行记录的属性编辑页面发现值根本没改,所以所没有进行二次查询数据库了,利用的是缓存。即便是你调用了初始化查询数据库的那个方法,也是不行的,还是有缓存,最好的做法就是,抛弃上面的三种写法,只需要两步就可以实现刷新,第一初始化DataGrid的那个方法请求必须是URLRequest的,添加一个参数类似于
var u:URLVariables=new URLVariables("temp="+Math.random());
当然不一定非要是temp什么名字都行,然后在返回操作成功提示后调用这个初始化方法,你会发现真的起作用了。
其实建议关于URLRequest传参数的最好带上这个参数,也不费事,可以在很多场合下解决缓存不更新问题