创建企业框架-用Flex进行企业开发(一)

原文来自:http://www.insideria.com/2009/05/chapter-preview-building-an-en.html

内容:程序员在跟宇宙赛跑,他们在努力开发出更大更好的傻瓜程序,而宇宙则努力培养出更大更好的白痴。到目前为止,宇宙领先。

--Rich Cook

简介

从来没有过完美的设计。Flex框架在进步,我们感激Flex团队的软件工程师们让这个框架可扩展。本书涵盖了在企业软件开发中Flex框架的使用,我们将确认和促进这些在商务RIA中广泛应用的元件。

对大部分企业应用程序而言,程序开发主要涉及以下几个活动:

创建数据网格

处理表单

数据有消化

打印

如果你,构架工程师,可以通过将常用的任务自动化,在这些领域快速进步,那应用程序开发员们就可以少花些时间重复地编写同样的代码。关键就是在可重复使用的Flex元件里封装此代码,以创建可以收录到程序库的更“聪明”的元件。

第一章, 回顾了构架框架如Cairngorm, PureMVC 和Mate, 最后选定Flex框架这些框架主要帮助将代码分成多层,但是现在你将学会怎样通过促进现有的Flex元件,构建另外一种框架。特别是,本章说明了怎样构建一个框架,完全简化数据录入应用的创建:

确认常见的可重复使用的元件,减少在手动敲写代码时不可避免出现的错误;

选定元件内的构架模式的封装;

确定最佳方法,并且在具体的元件中执行,而非纸上谈兵;

你将学会继承一些现有的元件,从最基本的技巧开始,同时扩展简单的CheckBox,然后接触更为复杂的ComboBox元件。本章的后半部分探讨的是拓展每个企业应用都依赖的元件,即DataGridFormValidator

通过提供结合了程序员、商业分析师、设计师和高端用户的工作框架,你可以迅速简化企业应用程序的开发。

每一位WEB开发员都熟悉Cascading Style Sheets (CSS) 。CSS让设计师可以定义和更改应用程序的外表和感觉,而无需学习编程。当你随着本章逐步学习的时候,Business Style Sheets (BSS) ,作为企业应用开发员所熟悉的角色,可以让软件开发员给一个元件附加远程数据设置,而将编码工作最小化。例如,你会看到一个简单的资源文件怎样指导ComboBox (或任何其它元件) 在哪里获得数据,并且怎样显示数据。把它当成是数据扫描。有了BSS,你可以开发在企业应用里可高度重复使用的产出物。

在这个过程中,你会了解更多有关BSS和其它促进和自动化Flex元件的技巧。虽然这里,你不能构建整个框架(最后一章探讨了打印和报告的问题),你将开始学会掌握有价值的技能,这些技能是任何Flex构架工程师和元件开发员必备的。

更新现有Flex元件

Flex是作为HTML对象模式的Flash框架进化而来的。它利用了HTML的简明性,是Flex控件的基本集。Flex开发员所要付出的“代价”就是:每一个控件都有其自己的(不同的)属性和行为。这样,构建一个企业框架就成为了挑战。CheckBox控件就是个例子。

为了快速把CheckBox并入不同的框架,开发员希望元件具有统一的属性onoff),可轻松地绑定到应用数据。现在,Flex的CheckBox具有一个属性为“选定”。开发员需要编写代码将Yes/No数据转换成选定的属性所期待的真或假。如果你随后使用另外一个控件,你必须再将这些Yes/No值转换成新的控件所要求的表单。很明显,一些共同点会减少冗余编码。

下面的章节会进一步探讨CheckBox 及其它每个应用程序都需要的主要的Flex元件,指出它们的缺憾,以及改进的方法:

元件程序库 clear.swc

你可能记得在第一章选定Flex框架的比较里,Clear Toolkit的元件程序库 clear.swc包含了许多强化的Flex元件(Figure 3.1, “The com.farata.components package from clear.swc”). 特别是,该元件程序库由三部分组成:

com.farata.components

com.farata.grid

com.farata.printing

为了展示怎样拓展元件,在下面的章节里,会说明我们是怎样从package com.farata.component里构建一些元件。如果你决定创建一个相似(或更好)的元件程序库,这些可给你提供一些参考。

将clear.swc与你的Flex项链接,你就可以独立使用clear.swc了。为了让你更好地了解其元件对你的帮助,下面将检测程序库一些控件的简化版:

创建价值识别CheckBox

Example 3.1 里的CheckBox, “具有值性和文本属性的CheckBox” 已经添加了额外的值性和文本属性进行强化。你可以确定要触发的值,以调制此控件的开/关。

 

 

CheckBox将自动设置成“选定”或“非选定”状态:添加到你的视图里,设定ON/OFF值,赋字符串或对象值。请注意值设定项调用函数invalidateProperties(), 该函数内部安排在下一个UI更新调度程序调用函数commitProperties()。

commitProperties()函数可以让你一下子就改变一个元件的所有属性。这就是为什么我们在该函数里根据_value和 onValue的比较结果设定选定属性的值。

Example 3.1, “价值识别CheckBox的测试应用” 是一个测试应用程序,说明怎样采用Figure 3.2, 使用CheckBox在“Testing the value-aware CheckBox”里显示的结果。为了运行测试,点击第一个Set OnValue= button,让CheckBox在赋Male 值的时候打开;在属性文本的值是Female的时候关闭。然后,点击第一个或者第二个cbx_test.text 按钮赋值给该CheckBox新引入的属性文本,观察它的状态怎么变化。

Example 3.2.价值识别CheckBox的测试应用

 

 

Figure 3.2.价值识别CheckBox的测试

创建中心的CheckBox

该范例展示了怎样在任何容器里,包括数据网格单元里,创建一个可以以自己为中心的CheckBox(水平方向)。

尽管你可以引入一个使用HBox内的CheckBox的条目渲染器,设置horizontalAlign的风格为“center”, 使用条目渲染器内的容器对数据网格控件的性能有负面影响。

更好的办法是:拓展CheckBox自身的风格。这里是一个代码扩充,“教导”标准的Flex CheckBox对textAlign风格做出反应,如果CheckBox的labelproperty未定义的话

Example 3.3. CheckBox的自定心解决方案

 

 

在上面的代码里,CheckBox图标的x座标将位于封闭容器的中心。因为不会引入额外的容器,你可以使用具备风格选择功能(style selector)的DataGridColumn条目渲染器。当你使用这个强化了的CheckBox做为数组条目渲染器,textAlign 就会自动改变为该风格选择器的一个风格,而你可以简简单单地设定set textAlign=true on DataGridColumn

当为企业商务框架开发强化元件时,重点确认应用程序开发商经常需要的可重复使用的功能,立即编写程序,将之加入元件本身。

创建受保护的CheckBox

标准的Flex CheckBox有一个Boolean属性,当你想要禁用控件时,非常便捷。不过,禁用CheckBox被视为“变灰”。如果你想在一些不可编辑的容器里使用CheckBox,比如DataGridColumnand里,你想让它不可更新,但是看上去正常,该怎么办呢?

答案就是:使用一个新的类,CheckBoxProtected。它包含一个额外的可更新属性,窍门就是取消标准键盘和鼠标点击处理。添加:

if (!updateable) return;

可覆写事件处理函数;

很灵喔!

Example 3.4, “Class CheckBoxProtected” 列出了完整源代码:

Example 3.4. Class CheckBoxProtected

 

 

测试受保护的CheckBox,使用Example 3.5, “Test application for CheckBoxProtected”.

Example 3.5. Test application for CheckBoxProtected

 

 

运行应用程序,会产生Figure 3.3, “Running CheckBoxProtectedApp” 所列结果。它显示了受保护和禁用checkboxes之间的区别。

Figure 3.3. Running CheckBoxProtectedApp

为什么不充分使用Flex框架的可拓展性呢?本章节讨论的是使用Flex元件你能够做什么。了解了这些,你将决定如何来使用这些元件。

例如,CheckBox的三态。底层的数据可能是Yes, No, 和 Null。如果值是Null (第三态),CheckBox 需要显示一个不同的图像,如里面是个小小的问号。除了支持三态(选定,未选定和null)外,控件应该支持从一个状态到另外一个状态的轻松转换。此强化方案包括一个skinning任务-在Photoshop里创建一个新的皮肤(带一个问号),确保控件根据底层数据转换到此状态。如需实例,参见CheckBox3Stated in the clear.swc component library。

更新ComboBox

CheckBox是最容易强化的,因为它是最简单的控件之一,只有两个状态(on或off)。你可以将同样的原则施用于更高级的ComboBox。确认可重复使用的功能,立即编写程序,将之加入元件本身。

如果你需要请求在ComboBox里选定一个特定的值,传统的做法就是编写在ComboBox数据提供者里轮巡条目表的代码,并且手动处理selectedIndex属性。设定Texas 为渲染状态的ComboBox的一个选定值,你可使用:

 

 

 

它看上去不像风格吗?你也可以通过如,改变Y/N的on/off值为Д./Н(在俄文里是Да/Нет)或者西班牙语的Si/No,轻松地将它设为本地特性。当你把此类资源看做独立于应用程序组件的实体时,你开始看到了此技术的灵活性。这个功能是不是和CSS相似?

实际上,它比CSS更为成熟,因为该资源是风格和属性的混合,如Example 3.9, “StateComboBoxResource with hard-coded states”所示。名为StateComboBoxResource.mxml,它显示了在BSS里对属性的利用(如dataProvider)。这样一种资源可包含一个值列表,如名称和状态缩写:

Example 3.9. StateComboBoxResource with hard-coded states

另外一个资源范例 Example 3.10, “Sample DepartmentComboResource configured for a remote destination” 包含了远程目的指引,以自动检索来自DBMS的动态数据。

Example 3.10. Sample DepartmentComboResource configured for a remote destination

 

事实上,你无法从此代码判断数据来自于 DBMS 或来自其他地方。。那样的数据明显和与这一特别资源相连的ComboBox对象的实例相分离,可以全局缓存(如果数据需要一次性检索到)或者依据框架缓存标准。在开发一个商业框架时,你可就每个应用程序或者每个视图上载一次查询对象。在基于单例的架构框架里不存在这样的灵活性。然而,利用资源技术/BSS创建框架则具备查询对象的灵活性。

基于此资源文件,你只能说数据从远程目的Employee(类的名称或类厂)处回来了。你也可以看到方法getDepartments()会返回包含DEPT_ID 和DEPT_NAME(与本章前半部分所述的强化ComboBox一起使用)的数据 (Example 3.6, “Class com.farata.control.ComboBoxBase”)。

然而除了这些资源外,你需要一个机制将它们附加到Flex UI元件上。为了指导

ComboBox 处理此类资源,添加一个资源属性:

 

基类“The Base Class for Resources”小节将详细探讨ResourceBase类。现在,我们的重点是,资源属性可以让你编写:

<fx:ComboBox resource="{DepartmentComboResource}

在你的框架里的每一个强化了的UI元件应该包括此类属性。因为接口不允许默认实现此类setter和getter,而且ActionScript不支持MI多继承。包含资源属性的默认实现的最简单的方法是:通过利用语言编译时期指令(包括外部文件,如resource.as,的内容),包含到你的元件代码里:

#include "resource.as"

风格 VS. 属性

进一步深入BSS和资源方式之前,你需要了解风格和属性之间的一些关键区别。譬如,尽管简单的点标志(myObject.resource=value) 是属于有效的Flex语法,它不适用于风格。应用程序员们不得不使用函数setStyle()StyleManager处理级联式风格,而属性不能级联。从框架程序员的观点来说,属性允许getters和setters定义类,并且利用了继承的方法。但是你不能对风格进行此操作。另外一方面,你不能给风格添加属性(即值和目的)。

Flex框架的设计师们为了更简便的操作内部流程,将风格从属性里分立出来――如果应用程序代码改变了风格,Flex框架执行一些秘密任务以确保级联的风格得到了适当地应用;例如,给Verdana font family发出指令的全局风格被应用于Panel或其子实例的风格所覆盖。

从企业框架设计师的角度来说,这意味着如果你为风格创建了一个基类,随后决定改变它,这种改变可能会影响所有派生类。假设你划分ComboBox的子类,定义了派生MyComboBox里的一些新风格,然后你改变了ComboBox的风格。对于子代类而言,这就意味着需要新的代码更改以恰当地(根据更改了的规则)应用被重写和添加的风格。

所有这些说明为什么所有的书和产品手册都警告风格是“昂贵“的,你应该限制在运行时setSyle()函数的使用。有了属性,一切简单多了。

有利的框架能让应用程序员定义特殊应用风格和属性的小命名集,以及使用选择器管理UI控件的工作。

为此,进入DataGrid。

你是否想过DataGridColumn对象是怎样设定宽和高及其它值的?DataGridColumn类是一个风格选择器CSSStyleSelector的子代。这意味着可以用它来修改风格,而不是属性。

DataGrid检测每个DataGridColumn,并询问“在我的缓存里,我是否有和这个列对象一样的?”如果答案是否,它回答,“不,没有我可以重复使用的。我需要创建一个新的类工厂以提供一个新的条目渲染器。”完成这个任务后,DataGrid 代码将提供的DataGridColumn作为风格分配给条目渲染器。(自己搜索以DataGridBase.as为代码的forrenderer.styleName=c)。在这点,特定栏的所有风格(高、宽、颜色、文本对齐)被做为风格应用到条目渲染器上。

DataGridColumn 当成一个也包含有限定数量属性(如条目渲染器)的CSS风格选择器。DataGrid创建一个这样的选择器对象的实例,然后重新应用于该栏里的CELL单元。

不过,以这种方法设计DataGrid使得外部化这个CSS风格选择器几乎成为不可能;并且你也不能拓展数据网格栏的属性,以使得它们成为条目渲染器的特定属性。假定你想使用有属性值(on/off)的CheckBox做为条目渲染器。不好!--DataGridColumn不是动态对象,你不能仅仅就是添加这个作为新属性。

然而,Flex是一个可拓展的框架,你添加的是一个具有你更喜欢的行为的新资源类。实际上,这就是ResourceBase类的功能,下一步我们会进行说明。

这个方法的不利之面就是:如果你的应用程序有了50个ComboBox控件,开发员们可能会编写类似的循环程序,而不是单行,如cbx_states.value="Texas"

但是,ComboBox并不提供包含选定值的特定属性。它包含有此类属性如labelFieldselectedIndex, 和selectedItem。它们中的哪个才是数据场?怎么通过值搜索?你真的在意ComboBox里选定行是哪行?不是。你需要了解选定值。

让我们再看下上面的代码段。ComboBox 的labelField从存储在后备存储器里的对象上得知属性的名称。但是与此标签通讯的数据场又是怎样呢(如Texas, TX 是一个很适合的ComboBox数据)?现在,找出此类数据是应用程序员的一个任务。

即使你不在意这些循环程序,考虑到填充数据提供者的异步性,此代码需要等到来自服务器数据的到来。如果你仅仅是赋值到一个ComboBox,也是可以的,你也无需担心事件的异步流。

考虑列表控制,ComboBox的同伴。譬如,用户选定五个条目,然后决定过滤备份数据存储器。用户的选择会丢失。列表同时也要求另外一种属性,可记忆选定的值,并且在使用时无需担心数据达到时间。

Example 3.6, “Class com.farata.control.ComboBoxBase” 提供了解决方案ComboBoxBase类(通过添加值拓展ComboBox,勿混淆)。在引入值性后,它利用数据场的属性告知ComboBox与该值通讯的底层数据存储器的对象里的数据场的名称。新的数据场属性可以让你把任何专用对象属性做为ComboBox数据。

你还会注意到另一个更公开的属性:keyField。从技术上讲,keyField是数据场dataField的同义词。你可以利用keyField来避免在其它也有属性为dataField的对象(如,DataGridColumn)里使用ComboBoxBase或其子类时命名的冲突。

Example 3.6. Class com.farata.control.ComboBoxBase

 

新的属性值根据下面的属性值设定函数设定赋予:

 

注意当函数开始改变flag _value时,无效的Properties ()会内部安排调用方法commitProperties() 以确保所有的改变都会应用在所要求的序列中。在本例中,commitProperties()函数里的代码确保数据场的值在值性有明确改变(如有)之前就会得到处理。

ComboBox是异步控件,可通过服务器端调用予以填充。当你向值性赋数据时,不能确保远程数据会准时达到。在设值器里的_candidateValue是一个临时的支持性推迟赋值,采用方法commitProperties()

函数commitProperties() 通知值已被改变(如果其它应用程序对象与该值绑定),并且向方法applyValue()传递_candidateValue:

 

方法applyValue()使用IViewCursoriterator在dataProvider里轮巡收集系统。当此代码在数据收集系统(具备在数据场里指定的属性,其值与该函数的引数相同)找到对象,它将此行标志为“选定”:

 

 

以确保相应的属性会出现在Flex Builder的设计模式里的ComboBoxBase的属性对话框里(在本例中,是在General目录下,特定初始值indefaultValue和verbose)。Metatags 如[Bindable("dataFieldChanged")]确保一旦dataField值改变,dataField 更改事件会被发送(至关注者)。

小应用程序TestComboBoxApp.mxml 显示对ComboBoxBasecomponent的使用。

Example 3.7. Using the ComboBoxBase component

 

 

两个下拉框使用相同的dataProvider。当运行Example 3.7, “Using the ComboBoxBase component”'的应用程序时,你会看到一个与Figure 3.4, “Running an application with two ComboBoxBase components” 里相似的窗口。窗口:

Figure 3.4. Running an application with two ComboBoxBase components

 

第一个ComboBoxBase 显示Farata System,因为赋值="FS" 将之比较了来自cbData collection 收集系统的对象的数据场内的值。

第二个下拉框设定dataField="taxID" ,指导ComboBox利用底层数据收集系统内taxID属性的值。如果代码将赋一个新值totaxID, 即,外部数据更新,ComboBox内的选择会相应改变。它更好地与现实的情况联系起来了。在现实的情况里,来自服务器的具备多项属性的DTO收集系统到达,与一个或多个ComboBox控件一起使用,而ComboBox控件可能把不同的DTO属性作为它们的数据。

作为UI控件属性的资源 

如需强化元件以更好地支持你的企业框架,一个更为灵活的解决方案就是使用一种我们称之为data styling或Business Style Sheets (BSS)的编程技术。基本的过程就是:创建叫做资源(resources)的小文件,然后将它们做为属性附加到通常的UI元件和DataGrid column上。

Example 3.8, “A CheckBox resource” 显示了此BSS 技术 ,并包含了一个小MXML文件叫YesNoCheckBoxResource.mxml:

Example 3.8. A CheckBox resource

 

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值