免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 5734 | 回复: 0
打印 上一主题 下一主题

FLEX中使用AS动态创建DataGrid [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-02-12 15:34 |只看该作者 |倒序浏览
初学FLEX时,需要在AS里动态生成DataGrid,结果搞了很久才搞明白怎么把用MXML写出来的DataGrid改成用AS写出来,其中最主要的就是自定义itemEditor、itemRender怎么写,写篇东西整理总结下。

先看看下面这段代码:
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
  3.         <mx:Script>
  4.                 <![CDATA[
  5.                         import mx.collections.ArrayCollection;
  6.                         import mx.controls.DataGrid;
  7.                         import mx.events.ListEvent;
  8.                         [Bindable]
  9.                         private var dgDataArr:Array = [{name: "Jon", job: "officer"},
  10.                                                                           {name: "James", job: "seller"},
  11.                                                                           {name: "Jodon", job: "manager"}];

  12.                         private function itemClickHandler(e:ListEvent):void
  13.                         {
  14.                                 trace(e.target);
  15.                         }

  16.                 ]]>
  17.         </mx:Script>
  18.         <mx:Component id="comboboxEditor">
  19.                 <mx:ComboBox dataProvider="{dt}" editable="true">
  20.                         <mx:Script>
  21.                                 <![CDATA[
  22.                                         private var dt:Array = ["officer", "seller", "manager"];
  23.                                 ]]>
  24.                         </mx:Script>
  25.                 </mx:ComboBox>
  26.     </mx:Component>
  27.         <mx:DataGrid width="100%" x="10" y="20" fontSize="14" dataProvider="{dgDataArr}" editable="true" itemClick="itemClickHandler(event)">
  28.                 <mx:columns>
  29.                         <mx:DataGridColumn dataField="name" editable="false" />
  30.                         <mx:DataGridColumn dataField="job" itemEditor="{comboboxEditor}">
  31.                         </mx:DataGridColumn>
  32.                 </mx:columns>
  33.         </mx:DataGrid>
  34. </mx:Application>
复制代码
代码实现的是创建一个DataGrid,其中job栏可以编辑,并且编辑器是自定义的一个ComboBox。效果如下:



现在看怎么用AS代替MXML创建同样的DataGrid。


1.先实现这一句:

1.<mxataGrid x="10" y="20" editable="true" width="100%" fontSize="14" dataProvider="{dgDataArr}" itemClick="itemClickHandler(event)"></mxataGrid>

写成AS大概是这样:
  1. private function init():void
  2. {
  3.     var dgData:ArrayCollection = new ArrayCollection(dgDataArr);
  4.     var dataGrid:DataGrid = new DataGrid();
  5.     dataGrid.x = 10;
  6.     dataGrid.y = 20;
  7.     dataGrid.editable = true;
  8.     dataGrid.percentWidth = 100;
  9.     dataGrid.setStyle("fontSize", 14);
  10.     dataGrid.dataProvider = dgDataArr;
  11.     dataGrid.addEventListener(ListEvent.ITEM_CLICK, itemClickHandler);
  12.     addChild(dataGrid);
  13. }
复制代码
可以看到,在MXML里统一使用XX=”"的形式,但写成AS却各有不同。我没看过书,刚开始也迷惑,怎么就不能dataGrid.fontSize = 14这样写呢。

看下文档,才知道,每个MXML组件后面的属性分三种:

1.Properties 正常属性,如x y width等,写成AS是 dataGrid.x = 10

2.Styles 样式属性,如fontSize backgroundColor等,需要通过setStyle()设置,如dataGrid.setStyle(”fontSize”, 14);,也可以通过设置其styleName属性绑定到页面的一个css里。如:



3.Events 事件属性,AS要使用事件侦听,itemClick=”itemClickHandler(event)”对应的是如dataGrid.addEventListener(ListEvent.ITEM_CLICK, itemClickHandler);。具体哪个属性对应哪个事件,就要查文档了。

其中width有点特殊,如果想设置百分比的宽度,不能用 dataGrid.width = “100%”,需要设置percentWidth,实际上在MXML设置width时如果有百分号,数值会传给percentWidth而不是width

还有一个属性比较特殊,就是dataProvider,它是一个实现ICollectionView接口的东西。如果传入的是Array,会自动转成ArrayCollection,如果是XMLList会转成XMLListCollection。这里直接传入一个ArrayCollection,是为了之后使用不同过滤函数时不用调用dataGrid.dataProvider而直接用dgData,如dgData.filterFunction = myFilterFunction

2.接下来添加列:
  1. var columns:Array = new Array();
  2. var col:DataGridColumn;
  3. for ( var i:* in dgDataArr[0] ) {
  4.     col = new DataGridColumn(i);
  5.     if ( i == "name" ) col.editable = false;
  6.     columns.push(col);
  7. }
  8. dataGrid.columns = columns;
复制代码
这里只有两栏属性,用for in有点浪费了,这里只是示例。一般用AS写DataGrid都是动态生成的,数据也不确定,都用遍历添加栏。

3.最后就是使用ComboBox编辑。
传给itemRender和itemEditor都必须是一个实现IFactory接口的东西,IFactory接口很简单,只有一个newInstance()函数,DataGrid在渲染每一栏和每一栏的编辑器时都调用这个函数,返回一个新的渲染器。DataGrid默认的渲染器是DataGridItemRenderer,编辑的渲染器是TextInput。用下面的语句就可以把某一栏的编辑器设定为ComboBox:
  1. var comboboxFactory:ClassFactory = new ClassFactory(ComboBox);
  2. col.itemEditor = comboboxFactory;
复制代码
ClassFactory是实现了IFactory接口的类,上面这样设定后,每次col这一栏编辑的时候就会调用comboboxFactory.newInstance()生成一个ComboBox实例。
如果就只是上面那样设置,结果就是编辑时跳出来的ComboBox没有值,也不允许编辑,怎样传值进去呢?
ClassFactory有个properties属性可以让你传值给每一个ComboBox:
  1. comboboxFactory.properties = { dataProvider: ["officer", "seller", "manager"], editable: true };
复制代码
编辑后,DataGrid会默认把编辑器的text属性值保存到dataProvider里,并传送到itemRender。如果这里的编辑器没有text属性,例如NumericStepper,就需要给栏目设定editorDataField属性,指定编辑后该去哪里取修改过的值。例如:col.editorDataField = “value”

如果想要有更大的自由度,也可以自己写一个实现IFactory接口的类,在newInstance()里返回一个实例就行了:
  1. package
  2. {
  3.         import mx.controls.ComboBox;
  4.         import mx.core.IFactory;
  5.         public class CustomComboBox implements IFactory
  6.         {
  7.             private var customData:Array = ["officer", "seller", "manager"];
  8.             public function CustomComboBox() { }
  9.                 public function newInstance():*
  10.                 {
  11.                         var combobox:ComboBox = new ComboBox();
  12.                         combobox.dataProvider = customData;
  13.                         combobox.editable = true;
  14.                         combobox.setStyle("fontWeight", "normal");
  15.                         return combobox;
  16.                 }
  17.         }
  18. }
复制代码
然后给itemEditor一个实例:col.itemEditor = new CustomComboBox();

这样,文章开头的那个MXML写的DataGrid就全由AS生成了。完整代码:
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" initialize="init()">
  3.         <mx:Script>
  4.                 <![CDATA[
  5.                         import mx.controls.dataGridClasses.DataGridColumn;
  6.                         import mx.collections.ArrayCollection;
  7.                         import mx.controls.DataGrid;
  8.                         import mx.events.ListEvent;
  9.                         import mx.controls.ComboBox;
  10.                         [Bindable]
  11.                         private var dgDataArr:Array = [{name: "Jon", job: "officer"},
  12.                                                                           {name: "James", job: "seller"},
  13.                                                                           {name: "Jodon", job: "manager"}];

  14.                         private function init():void
  15.                         {
  16.                             var dgData:ArrayCollection = new ArrayCollection(dgDataArr);
  17.                             dgData.filterFunction
  18.                                 var dataGrid:DataGrid = new DataGrid();
  19.                                 dataGrid.x = 10;
  20.                                 dataGrid.y = 20;
  21.                                 dataGrid.editable = true;
  22.                                 dataGrid.percentWidth = 100;
  23.                                 dataGrid.setStyle("fontSize", 14);
  24.                                 dataGrid.styleName
  25.                                 dataGrid.dataProvider = dgData;
  26.                                 dataGrid.addEventListener(ListEvent.ITEM_CLICK, itemClickHandler);
  27.                             addChild(dataGrid);

  28.                             var columns:Array = new Array();
  29.                                 var col:DataGridColumn;
  30.                                 for ( var i:* in dgDataArr[0] ) {
  31.                                     col = new DataGridColumn(i);
  32.                                     if ( i == "name" ) col.editable = false;
  33.                                     if ( i == "job" ) {
  34.                                                 var comboboxFactory:ClassFactory = new ClassFactory(ComboBox);
  35.                                                 comboboxFactory.properties = { dataProvider: ["officer", "seller", "manager"], editable: true };
  36.                                                 col.itemEditor = comboboxFactory;
  37.                                     }
  38.                                     columns.push(col);
  39.                                 }
  40.                                 dataGrid.columns = columns;

  41.                         }
  42.                         private function itemClickHandler(e:ListEvent):void
  43.                         {
  44.                                 trace(e.target);
  45.                         }

  46.                 ]]>
  47.         </mx:Script>
  48. </mx:Application>
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP