现在的位置: 首页 > 综合 > 正文

自定义真正的可重用Flex组件

2013年10月12日 ⁄ 综合 ⁄ 共 3380字 ⁄ 字号 评论关闭

来源:http://blogs.adobe.com/tomsugden/2009/12/writing_genuinely_reusable_fle.html

在企业的大项目里,经常要为Flex 类库写一系列可重用的组件。理论上一些相同的组件可以重复用在不同的模块和子模块的Flex 或 AIR 程序中,带来一致性和快速开发的好处。然而在实际中,存在些错误用法限制了组件的重用性。本文章解释是什么方法令组件可以真正重用,和强调一些在Flex SDK 里使用的技术,来编写出更具重用性的自定义组件。
什么方法令组件可以真正重用?
组件重用性存在不同等级。一个真正可以重用的组件应该可以接受任何类型打数据进行渲染。完全可以适应数组、动态Object或者是Kangaros(具体对象)的集合。Flex DataGrid 组件有这样一个属性。

  1. <mx:DataGrid dataProvider="{ kangaroos }">
  2.    <mx:columns>
  3.       <mx:DataGridColumn headerText="Name" dataField="name"/>
  4.       <mx:DataGridColumn headerText="Weight" labelFunction="calculateWeight"/>
  5.    </mx:columns>
  6. </mx:DataGrid>

注意 dataField 和 labelFunction 属性任何通知组件怎样从Kanagroos读取数据,而且没有对它有依赖。这两种方法可以使组件重用。即使开发人员不能对Kangaroo 对象修改。或者它在第三方类库,但是他们仍然很容易使用者些对象给DataGrid 渲染。
数据接口反模式
一个普遍的错误是把组件渲染的数据,去实现指定接口。例如:一个分布栏组件渲染简单图片,如下图:
[localimg=180,21]1[/localimg]
分布栏显示不同大小的地区。每个都有个标示。通过使用IRegion 对象数组进行设计。

  1. public interface IRegion
  2. {
  3.    function get label() : String;
  4.    function get size() : int;
  5. }

这个分类栏会通过IRegion接口来提取size 和 label 信息渲染每个区域。理论上这个接口令这个组件和具象解耦了。任何实现该接口的类都可以被渲染。实际上这是设计上的错误。使用Iregion 接口令重用性有了限制。使用这组件前,一定需要把这接口加载进原有的数据类里。 更坏的情况是,这些数据类可能在另外的类库,或是在另一开发小组。因而不得不把这接口加载进来。导致这组件并不是真正的可重用。
可重用的Flex SDK组件
Flex SDK 提供很多可重用的组件,它们的实现有以下一些标准方法:
1.可重用的Flex SDK组件
Flex SDK 提供很多可重用的组件,它们的实现有以下一些标准方法:
1.Data Fields
2.Data Functions
3.Data Descriptions、
4.Factory Objects
现在就说明下这些方法。使用这些技术可以令到自定义的组件具有真正的重用性。
Data Fields
Data field 是一个字符型属性。代表另外属性名称。例如:ComboBox 的 labelField 或者DataGridColumn 的dataField 、dataTipField 属性。

  1. <mx:ComboBox dataProvider="{ items }" labelField="name"/>

组件的实现是使用 dataField 去读取 items 属性值。如:

  1. for each (var item:Object in dataProvider)
  2. {
  3.     var value:Object = item[dataField];
  4.     // do something with the value
  5. }

这是个很简单的方法,但提供很大灵活性。这组件可以读取任何对象的任何属性。
Data Functions
Data Function 是个函数类型。代表另外函数的引用。如:ComboBox 的 labelFunction 或DataGridColumn 的 dataFunction 属性。

  1. <mx:DataGridColumn headerText="weight" dataFunction="calculateWeight"/>

这组件然后调用dataFunction,一般用data 的item 作为参数。如:

  1. for each (var item:Object in dataProvider)
  2. {
  3.     var value:Object = dataFunction(item);
  4.     // do something with the value
  5. }

这种方法和 dataField 差不多,但使用更灵活了。因为在组件渲染之前,可以通过函数来计算或格式化返回值。
Data Descriptions
Data description 是一个接口,组件可以使用它来分析渲染数据。开发者可以使用自己实现的接口来处理组件的渲染数据。在Tree 组件可以看到

  1. <mx:Tree dataProvider="{ items }">
  2.     <mx:dataDescriptor><my:MyDataDescriptor/></mx:dataDescriptor>
  3. </mx:Tree>

Tree 可以使用dataDescription 接口分析数据特性。如:

  1. for each (var item:Object in dataProvider)
  2. {
  3.     var isBranch:Boolean = dataDescriptor.isBranch(item, dataProvider);
  4.     // do something with the outcome
  5. }

这个方法非常强大,不过一般只用在复杂的组件。如 Tree。开发者如果要在Tree渲染一个新的类,他们要自行实现ITreeDataDescriptor 接口。
Factory Objects
Factory Object 是一个 IFactory 属性,用于动态生成实例。如:List 和DataGrid 的 itemRenderer 和 ComboBox 的dropdownFactory 属性。

  1. <mx:List dataProvider="{ items }" itemRenderer="my.package.MyItemRenderer"/>

这组件使用Flex SDK 的标准IFactory 接口来创建实例。

  1. var itemRenderer:Object = itemRenderer.newInstance();

然后把data items 给IDataRenderer 接口创建的实例赋值

  1. if (itemRenderer is IDataRenderer)
  2. {
  3.     IDataRenderer(itemRenderer).data = item;
  4. }

这种方法提供操作部分组件的视图外观。通过提供自定义的itemRenderer,可以达到完全不同的结果。处理数据的逻辑的复杂程度可以根据需求来决定。而且还可以封装在ItemRenderer 类里面。前面提到,组件使用工厂(Factories)时候,应该定义有意义的默认值。所以组件可以直接使用,不需要设置特别的Factories。所有的ListBase组件都提供了默认值。如DataGrid 默认是DataGridItemRenderer。
这里值得注意是Flex 编译器和IFactory 有特别关系。当这个属性在MXML 设置了,会自动装换成类名字,然后把ClassFactory 的实例嵌入到组件里。这样使得组件更容易使用,开发者不用手动去实例对象。只需指定类名或定义一个嵌入组件。
总结
当需要重用组件时,要记住这简单的规则:一个可重用的组件应该可以渲染任何类型的数据。最好的实现方法是遵守Flex SDK的约定:data fields, data functions, data descriptors 和 object factories。要注意的是反对使用自定义的接口来限制你的组件重用性。
附言
可重用组件习惯使用动态属性,这里做了些权衡取舍。因为访问动态属性比强类型属性慢。而且没有编译期的类型检测。然而它的好处是使用更灵活,更少依赖。

 

最后,休闲一下,介绍下偶老婆滴:毛绒玩具,淘宝:http://shop34123388.taobao.com/

抱歉!评论已关闭.