Flex由以下几部分组成:
ActionScript3.0、Flash Player9(FP9)、Flex SDK、Flex Builder3
Flex Builder,当单击Run按钮时,到底发生了什么?事实上,此时会触发大量的进程。首先,应用程序文件中的XML标签被转换成ActionScript。ActionScript接下来被用来生成SWF文件,SWF是Flash Player能理解的格式。最后,SWF文件又被发送给浏览器中的Flash Player。
Flex允许在一个容器中分配超过100%的总宽度。Flex布局管理器(Flex Layout Manager)考虑到这一点,会根据请求的百分比分割控件。由于请求的控件是可用空间的两倍,两个百分比宽度的请求都被除以2,所以它们每个都分配到了50%。如果给任何元素分配了固定宽度(也就是分配了像素数而非百分比),以百分比宽度方式分配可用空间之前会减去固定宽度部分。
<xm:Image source=”@Embed(‘asserts/dairy_milk.jpg’)” scaleContent=”true” />
此@Embed指令会使编译器在编译时将JPG嵌入到SWF文件中。与运行时加载图片相比,本技术有两个优势。第一,图片在应用程序开始时就已经加载,因此用户不需等待图片显示。第二,本技术在构建不访问因特网的离线应用程序是很有用,因为需要的图片已经被包含在SWF文件中,直接可以正确显示。然而,请记住,使用该技术会显著增加SWF文件的大小。
当开发这要根据用户事件执行某些操作时,会发生以下几件事:
1. 用户与应用程序交互。
2. 用户所交互的对象分发了一个用户事件。
3. 事件被正听到并被处理。
4. 与事件处理程序相关联的代码得以执行。
到目前为止,当给一个属性赋值时,可以采用两种类型的值:标量值或者绑定。标量值是简单数据类型,比如字符串、数字或者布尔值。你先前设置属性时已经用过了标量值,比如x坐标、y坐标、宽度以及标示值。同样,绑定也已经使用过。给属性值使用花括号({})使用的就是绑定。
为事件赋值时,Flex编译器便将花括号理解为ActionScript代码。所以能直接输入ActionScript作为时间的值而无需花括号。可以看到,前一示例正是如此:click=”myL.text=’Button Clicked’”。
一般来说,但一个组件已经实例化并已正确地位于应用程序中时,会分发creationComplete事件。当creationComplete事件被分发时,组件会被用户见到,除非其visible属性被设置为false。Application对象的子元素(Application容器中的所有组件)都已广播了各自的creationComplete事件以后,Application对象才会分发自身的creationComplete事件。
在实践中,很少会嵌入XML数据。实践中更好的方法是使用HTTPService类在运行时加载XML。
Flex遵守Flash Player的安全沙箱限制,这意味着Flash Player会阻止一个域中的应用程序加载另一个域中的数据。在www.mysite.com中加载的应用程序要想自动获得访问www.yousite.com上数据的能力,必须使用跨域策略文件。这类文件的名称是crossdomain.xml,位于SWF文件调用的Web服务器的根目录下,制定了哪些域能通过Flash Player访问其中的资源。下面是一个跨域策略文件的例子,它可以允许任何SWF访问跨域策略文件所在服务器上的可用资源。
<cross-domain-policy>
<allow-access-from domain=”*”/>
</cross-domain-policy>
浏览URL www.flexgrocer.com/crossdomain.xml可以查看在本书中允许从数据源获得数据的跨域文件。同样,可以查看www.cnn.com/crossdomain.xml,查看CNN允许谁使用Flash Player摘取CNN上的内容。
普通数组对于在Flex中存储数据也很有用,但假若想将数据填入控件或者正以过滤、排序等手段操作数据,则ArrayCollection才是应该选择的数据结构。
使用一个常规的Array对象作为数据提供者是不对的。它虽然能再首次使用时将数据填入组件,但Array中的数据发生更改时组件不会更新。
组件的优势:
1. 组件让应用程序更容易编写、调试和维护。
2. 组件是团队开发变得容易。
3. 若有足够的规划,组件就能引领你编写整套可重用的代码。
为了便于在使用组件时写出可重用的代码,应该尽量减少它们对其他代码的依赖。组件应该作为应用程序逻辑中的一个独立部分,能够清晰地定义出组件需要传入什么数据,以及从组件会返回什么数据。面向对象术语松耦合应用于这类架构中。
MVC是一种设计模式,也是软件架构,它能将应用程序的数据、用户界面和控制逻辑分为不同的3组。它的目标是实现逻辑以使应用程序中的部分改变只最低限度地影响其他部分。其中关键术语的简短定义如下:
1. 模型。应用程序用到的数据。它管理数据元素,对有关其内部状态的请求做出响应,并处理要更改数据的指令。
2. 视图。用户界面。视图的职责是将模型数据呈现给用户,并从用户收集信息。
3. 控制器。对事件的响应。典型代表使用户事件,但也包括系统事件。控制器解释事件,然后对模型和视图进行调用并更改其中的数据和界面。
通常来说,MVC的流程如下所示。
1. 用户在用户界面(视图)上进行交互,例如为了将项目添加到购物车而单击按钮。
2. 控制器处理输入事件。
3. 控制器访问模型,可能是获得数据或者修改数据。
4. 使用模型数据以适当的方式将视图呈现给用户。
为了访问应用程序的顶级属性和方法,可以使用mx.core.Application类中的application属性,该属性提供了对Application对象的应用,在Flex应用程序的任何地方都可以使用它。虽然这样做是可以的,但是还应该仔细权衡是否使用它,因为它将导致各组件之间紧密耦合,这恐怕就不是最佳做法了。
理解Flash Player如何处理事件是很有用的。不论何时触发事件,Flash Player都会发布事件。如果事件目标不是屏幕上的可视元素,Flash Player可以直接向指定目标发布时间对象。例如Flash Player会直接向HTTPSerivce组件发布result事件。然而,如果目标是屏幕中的可视元素,Flash Player发布事件时会让事件从最外部容器(即Application容器)开始向下传递目标组件,然后回到Application容器。
事件流从概念上可分为3各部分。
1. 捕获期包含了从根应用程序到事件目标之间的所有容器。
2. 目标期由目标节点单独构成。
3. 冒泡期包含了从目标返回根应用程序过程中遇到的所有元素。
创建ActionScript3.0组件所需的步骤与创建任何ActionScript3.0类的步骤相似。首先,确定新类要扩展的基类(如果要进行扩展的话)。然后,确定需要为类声明的属性。接下来,确定需要首先的新方法。还需要声明组件会分发的事件。如果组件式可视类,很可能需要重写createChildren()和updateDisplayList()方法,因为Flex组件在创建、更改大小和布置任何子元素时会使用这两个方法。
ViewStack类是Flex导航的核心,也是一个Flex容器组件。它是其他容器或者子容器的集合,这些容器互相堆叠在彼此的上方,因此每次只有一个容器可见。必需添加功能来控制每次要显示的子容器。ViewStack只能将其他容器作为子容器,其中包含其他导航容器。如果将非容器的组件用作ViewStack的子容器,会发生运行时错误。
尽管ViewStack是Flex中实现导航的关键元素,但它本身却不能将组件切换为可见,必需使用别的工具才能将容器切换为可见。
Flex允许子标签和子容器占据页面上相同的x标签和y标签。根据在MXML中的声明顺序,每个子容器都占据一个不同的初始深度(z轴位置)。
RIA中有一个非常重要但往往被忽视的需求,即需要在浏览器中使用后退和前进按钮。基于Web应用程序的大多数用户已经习惯用这些按钮来导航Web页面了,并且为你的Flex应用程序实现这个功能也是很有意义的。
Flex中的所有导航容器都自动支持历史管理,不需要使用额外的MXML或者ActionScript标签。
Flex进行历史管理时使用Adobe Flash Player的navigateToURL()函数保存了程序的各个状态。这个函数是一个不可见的HTML框架加载到了当前浏览器窗口,将Flex应用程序的所有状态编码成该HTML框架的URL参数。该HTML框架中的一个SWF文件(名为history.swf)会将查询参数进行解码,并将导航状态信息发回Flex中的HistoryManager类-该类显示以保存的数据。
用没有默认实现你是管理的组件来实现历史管理需要以下6个步骤。
1. 该组件需要实现IHistoryManagerClient接口。
2. 用HistoryManager类注册该组件。
3. 在该组件中实现loadState()方法。
4. 在该组件中实现saveState()方法。
5. 在该组件中实现toString()方法。
6. 调用HistroyManager类的各种静态方法。
如果用个是Internet Explorer,可能会遇上运行时错误。因为Internet Explorer对JavaScript的执行有一些安全限制,所以在本地执行的应用程序的历史管理功能会有问题,而只有运行的应用程序是从服务器上获取时才能用历史管理功能。Firefox没有这个问题。
深度链接用来描述应用程序对于基于URL导航的支持,它通常表示一个URL。Flex应用程序与传统的基于HTML的 Web应用程序不同,它本身并不是相互链接的、有着各自URL的若干不同页面。但Flex则完全不同,整个Flex应用程序一般是通过一个URL访问的。因此改变浏览器的URL会遇到一些挑战。通常,在运行Flex应用程序时改变URL,浏览器就会卸载当前的程序并加载新的请求页面。这使得一些功能很难实现,比如将代表程序特定部分的URL发到各户的邮箱或使用户可以在程序里用书签标记特定的位置。为了解决这个难题,Flex内置了对深度链接的支持。
深度链接允许URL代表Flex应用程序的不同“页面”,而不是在改变URL是关闭应用程序。这个特性使用锚点(即URL中的#号后面的参数,通常用于HTML页面内不同位置的导航)。用锚点实现深度链接时,URL的主题没有改变,因此浏览器不会卸载当前程序并装载新的程序。想法,改变的只是锚点,程序可以读取其变化并作出反应。URL中#号后面的部分通常被叫做片段。当改变片段时,浏览器历史会保存前一个片段,使用户可以用浏览器的前进和后退按钮在程序中来回跳转。
Flex3是通过BrowserManager类来实现深度链接的。BrowserManager支持对片段和浏览器标题的读写,还能在片段发生改变时为程序提供通知。
你可以使用两种不同的方式来设计Flex应用程序:样式和皮肤。
样式属性可以用来修改Flex组件的外观,他们可以设置字体大小、背景颜色和许多其他预定义的样式属性。
皮肤是另一种定制Flex应用程序外观的方法。皮肤是图形元素(以文件形式存在或者用ActionScript绘制),可以用来替代组件各个状态的默认外观。
样式属性的小写字母连字符版本仅仅适用于传统CSS中的属性。Flex特有的属性(比如rollOverColor)只能使用大小写混合语法。
运行时修改CSS具备很多优点,其中最主要的优点是维护程序的速度更快,因为设计人员可以很容易地将新版本的CSS部署到Web服务器,而不需要重新编译和部署应用程序。另一个优点是,它提供了更加简单的方式来部署呈现了多个皮肤的应用程序,而不需要分别为每个皮肤部署一个应用程序。
因为Flash Player本身不具备在运行时直接加载CSS文件的能力,而Flash Player能够轻易地与SWF进行交互,所以Adobe增加了一个将现有CSS样式表转换为SWF的简单机制。通过SDK,可以用MXMLC编译器编译为SWF。
使用编译为SWF的CSS文件很容易,你只需要用一行ActionScript代码就可以加载和使用该文件。
Stylemanager.loadStyleDeclarations(“flexGrocer.swf”);
这行代码指示StyleManager加载指定的文件,并使用文件中指定的样式。
如果需要与在自动加载的CSS文件,可以使用StyleManager中的另一个方法:unloadStyleDeclaration。
sytleManager.unLoadStyleDeclaration(“flexGrocer.swf”);
处理多个样式表的基本原则是,如果某个样式在多个样式表中都存在定义,那么程序使用最后被加载的那个样式。
虽然定义特殊的图标需要使用大量不同的标签,但是一般而言,大部分图标遵循以下结构。
<ChartType>
<!—Define the axes. -->
<mx:horizontalAxis>
<mx:AxisType>
</mx:horizontalAxis>
<mx:verticalAxis>
<mx:AxisType/>
</mx:verticalAxis>
<mx:series>
<mx:SeriesName/>
</mx:series>
<!—Style the axes and ticks. -->
<mx:horizontalAxisRenderer/>
<mx:verticalAxisRenderer/>
<!—Add grid lines and other elements to the charts. -->
<mx:annotationElements/>
<mx:backgroundElements/>
</ChartType>
<mx:Legend/>
Flex开发者现在可以选择桌面部署。基于浏览器的应用程序与桌面应用程序相比,它存在一些限制,这一点Web开发者并不一定知道。举例如下。
1. 浏览器不允许应用程序访问文件系统。
2. 基于浏览器的应用程序在保存客户端数据时会受到限制:HTML应用程序保存在cookies,Flash Player应用程序保存在共享对象(Shared Objects)中。
3. 基于浏览器的应用程序不能运行后台服务,他们只能和运行在开放浏览器中。
4. 基于浏览器的应用程序很少是离线程序,它们依赖于连接因特网。
5. 浏览器设置占用了许多快捷键。基于浏览器的应用程序不能把这些快捷键设置成其他含义。
AIR是Web开发者的另一个选择。它们可以使用自己熟悉的技术在浏览器的外部构建应用程序。AIR可以摆脱浏览器的所有限制。
1. AIR应用程序可以直接访问文件系统。
2. AIR应用程序支持把操作系统的项目直接拖放到应用程序中。
3. AIR应用程序可以使用窗口API,可以完全定制应用程序的外观,也可以创建“后台”程序,隐藏它。
4. AIR提供了一组强大的API来部署不完全连接因特网的应用程序。
5. AIR应用程序存在于浏览器之外,所以没有设置快捷键的限制。
6. AIR提供了嵌入式数据库,支持更强的客户端存储能力。