`
bufanliu
  • 浏览: 197384 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Flex 模块化应用程序开发

    博客分类:
  • FLEX
阅读更多
如果你没有看过Roger Gonzalez的Blog中关于模块(Module)的文章,那么你应该去那里了解一下Flex 2这个特性背后的细节和想法。这里我不想过多地探讨为什么要这样,而是想要给大家展示一个使用了模块(Module)的简单的Flex程序,你可以从中获得启示。

示例源码

你可以下载关于这个例子的压缩文件:点击这里下载

模块(Modules)

模块(Module)是创建大型Flex应用程序的一个解决方案,它允许你将你的用户接口分割成许多分散的有各自用途的小块。例如(下面出自Flex 2的文档),一个保险公司可能有数百个表单——针对于各个领域的,针对各种请求类型,以及针对各种应用等等。创建一个包含所有这些表单的Flex应用程序将会产生一个巨大SWF文件,还会有不少问题:
  •应用程序越大开发过程越复杂;
  •应用程序越大测试过程越复杂;
  •应用程序越大部署过程越复杂;
  •SWF文件越大加载时间越长

我的示例程序基于Flex 2文档中的一个程序,但是我将它做了一些更改来说明几个常见的问题。这个例子展示了一个主程序和其它三个共享公有数据的模块(Module)。

其中一个设计要素是一个接口的使用,这个接口实质上是接口实现者和使用者之间的一个契约。这个例子将会说明我所说的意思。模块(Module)的接口部分虽然不是必须的但是却可以大大简化以后的开发和维护。比如,如果开发人员有一个小组负责报告部分,另一个小组负责图表部分,如果它们一开始用了接口,那么只要有需要,接口的实现就可以做足够多的变形而不会影响到工程结果。接口在模块(Module)中还扮演另外一个角色,我在下文中将会揭示这点。

模块(Module)是以<mx:Module>代替<mx:Application>作为根标签的MXML文件(或ActionScript文件)。你可以将带有<mx:Module>标签的作为一个程序来看,但是它不能运行。

这个示例有一个主程序文件以及带有一个接口的两个模块。打开主程序文件你会看到:



程序代码
<mx:Panel x="10" y="41" width="169" height="500" layout="absolute" title="Modules">
      <mx:Text x="10" y="24" text="Check a module to load it; uncheck to unload it" width="129"/>
      <mx:RadioButton x="10" y="97" label="None" selected="true"
                          click="removeModule()"/>
      <mx:RadioButton x="10" y="123" label="Chart"
                         click="removeModule();loadModule('ChartModule.swf')"/>
      <mx:RadioButton x="10" y="175" label="Table"
                        click="removeModule();loadModule('GridModule.swf')"/>
</mx:Panel>

<mx:Panel x="187" y="41" width="500" height="500" layout="absolute" title="Module: {moduleName}">
       <mx:ModuleLoader id="currentModule" ready="readyModule(event)"
                       width="100%" height="100%" />
</mx:Panel>


第一个Panel包含了控制示例中模块(Module)加载和卸载的RadioButtons。第二个Panel是使用<mx:ModuleLoader>标签加载模块(Module)的地方。注意那个id为currentModule的ModuleLoader,它有一个关于ready事件的事件处理器。当模块SWF文件加载了足够多可以开始使用的时候,ModuleLoader 就会分派ready事件(或者说ModuleEvent.READY)。

这里有一个readyModule函数,它在<mx:Script>块中:



程序代码
private function readyModule( event:ModuleEvent ) : void
{
       var ml:ModuleLoader = event.target as ModuleLoader;

      var ichild:IExpenseReport = ml.child as IExpenseReport;
      if( ichild != null ) {
               ichild.expenseReport = expenses;
      }
}


注意ModuleLoader的child属性是如何转换为IExpenseReport类的。IExpenseReport是一个所有模块(Module)都实现了的接口。只要每个模块都实现了这个接口,它就可以很容易适应于应用程序。换句话说,想象一下当你需要创建另一个表单或者报告的时候它的用途。并不需要更改主程序为新模块添加IF语句,你只要在新模块中实现IExpenseReport接口它就可以在程序中完美地运行。

IExpenseReport接口是:



程序代码
public interface IExpenseReport
{
      function set expenseReport( ac:ArrayCollection ) : void;
}


每个模块(Module)都实现这个接口,定义各自的名为expenseReport的set函数。下面是ChartModule的根标签和接口IExpenseReport的实现:



程序代码
<mx:Module xmlns:mx="http://www.adobe.com/2006/mxml" implements="IExpenseReport"
            layout="vertical"
            percentWidth="100" percentHeight="100" >
     <mx:Script><![CDATA[
           import mx.collections.ArrayCollection;
           [Bindable] public var expenses:ArrayCollection;

           public function set expenseReport( ac:ArrayCollection ) : void
           {
                 expenses = ac;
            }
     ]]></mx:Script>
...
</mx:Module>


让我们回到主程序,RadioButton的click事件会卸载任何当前已加载的模块然后加载一个新的模块。下面是ChartModule的RadioButton标签:



程序代码
<mx:RadioButton x="10" y="123" label="Chart" click="readyModule('ChartModule.swf')"/>


这个click事件会调用上面列出的readyModule事件。

编译并运行程序

如果你使用了Flex Builder 2,请确定更改了项目的Properties将模块(Module)作为"Applications"包含进来。这样Flex Builder 2回将它们编译进SWF文件并且放进bin文件夹中。

Flex Builder注意:要创建一个使用模块(Module)的工程,请使用工程的Properties将模块文件作为"Applications"。这会使得他们被编译进SWF文件。

一旦SWF文件被创建你就可以运行主程序并点击RadioButtons在模块(Module)之间切换。

Flex Builder注意:Flex Builder并不会保存任何关于模块(Module)和主程序的从属信息。只要你对一个模块(Module)作了更改,你就可能需要重新编译主程序或其它从属的模块(Module)。

将SWF文件最优化

如果你查看一下主程序的SWF文件和模块(Module)的SWF文件的话,你会发现它们的大小差不多。这就说明,模块的SWF和主程序SWF中有很多同样的组件定义。

Flash Player并不会保存元件(symbol)的副本。例如,如果主程序有一个Button组件而一个模块(Module)也有一个Button组件,Flash Player就不会从模块中加载Button了,因为它已经在主程序中有定义了。

使用-link-report=report.xml编译主程序,这样会创建一个链接到主程序的包含所有元件信息的文件。然后在编译模块(Module)的时候会使用那个report.xml文件。



程序代码
mxmlc -load-externs=report.xml ChartModule.mxml


当ChartModule被编译的时候,所有在report.xml文件中列出的元件将会在它的SWF中省略。当我不使用report.xml文件编译ChartModule.swf的时候,它的大小是202K。而当我使用report.xml文件的时候,SWF的大小只有68K。这大大减少了模块(Module)的加载时间。

在文章的开始将到模块(Module)的时候,我提过接口有另一个作用。假设你没有使用接口而是在主程序中引用模块的类。当你运行link-report的时候,你的模块类将会出现在report.xml中。当你使用使用link-report编译模块(Module)的时候你的模块并不会包含在它自己的SWF中!起初这并不会成为一个问题,尽管主程序由于包含了模块的定义而变得很大。然而,当你更改你的模块的时候发生了什么才是重要的。如果你没有重新编译主程序,你主程序的SWF文件将会包含模块(Module)旧的定义——而不是你已经更改过的。



程序代码
mxmlc -link-report=report.xml Main.mxml
mxmlc -load-externs=report.xml ChartModule.mxml
// etc.


如果你决定使用这个技术来减小模块(Module)的大小,那么就使用接口来确保终端用户使用的总是模块(Module)的最新版本。

Flex Builder注意:Flex Builder在一个工程里没有办法做到这些。如果你确定你将要创建一个使用模块(Module)的工程,可以考虑一下将公共的类和接口(包括event类)放到一个SWC(Flex Library Project)中然后将模块(Module)分离到它们各自的工程里。

或者,你可以将所有东西创建为一个单一的Flex工程,然后将最优化作为一个产品化前或测试前的部署步骤在Flex Builder之外进行。

总结

•将程序分割成多块并不是每个人都会使用模块(Module)。使用这种方法主程序会比平常小,而且多数用户只使用整个程序的一部分。
•使用接口来使主程序或模块(Module)来与加载的模块通信。这使维护变得容易。
•使用-link-report命令参数编译主程序来产生一个使用元件列表。
•在主程序中使用-load-externs和report.xml编译模块(Module),这样可以使它们变得更小。
分享到:
评论
2 楼 lmhdlcode 2008-06-11  
给我回mail,lmhdlcode@gmail.com
thanks a lot
1 楼 lmhdlcode 2008-06-11  
有2个问题啊,望赐教。
1)在.actionScriptProperties文件中有如下代码
<applications>
    <application path="Main.mxml"/>
    <application path="ChartModule.mxml"/>
    <application path="FormModule.mxml"/>
    <application path="GridModule.mxml"/>
  </applications>
ChartModule,FormModule,GridModule的标签是<MX:Module>怎么会在配置文件中在<Application>中?

2)如果我的Main.mxml也是module,由另外一个Application来调用Main.mxml.如果把Main.mxml的标签由<MX:Application>换做<MX:module>则readyModule函数的ichild为空。。
private function readyModule( event:ModuleEvent ) : void
{
var ml:ModuleLoader = event.target as ModuleLoader;

var ichild:IExpenseReport = ml.child as IExpenseReport;
/**********************************************************
     iChild是空
***********************************************************/
if( ichild != null ) {
ichild.expenseReport = expenses;
}
}

相关推荐

    ActionScript 3.0 API文档及Flex开发详解电子书

    第4章 Flex模块化编程 第5章 ActionScript 3精要 第6章 Flex图表 PART 3 Flex 3 Web项目全案开发 第7章 Flex企业级开发实践—— Flex + Struts 第8章 Flex企业级开发实践—— Flex + Web Services PART 4 ...

    使用ADOBE FLASH BUILDER 4.5

    用于加快应用程序开发速度的功能 用于运行和调试项目的功能 Flash Builder 版本 Flash Builder 配置 Adobe Community Help Client (CHC) 第 2 章: Flash Builder 入门 Flash Builder 工作台 Flash Builder ...

    Angular-php-sf-flex-webpack-encore-vuejs.zip

    Angular-php-sf-flex-webpack-encore-vuejs.zip,一个简单的应用程序框架,试图使每个组件协同工作:...它专注于良好的移动开发、模块化和改进的依赖注入。angular的设计目的是全面解决开发人员的web应用程序工作流。

    robotlegs-framework:适用于Flash和Flex的ActionScript 3应用程序框架

    大大简化了模块(多上下文)支持快速开始创建上下文要创建Robotlegs应用程序或模块,您需要实例化上下文。 如果没有一些配置,上下文将不会做很多事情。 普通动作脚本: _context = new Context

    Angular-flex-layout.zip

    Angular-flex-layout.zip,为角度应用程序提供html ui布局;使用flexbox和响应式apiangular flex布局,...它专注于良好的移动开发、模块化和改进的依赖注入。angular的设计目的是全面解决开发人员的web应用程序工作流。

    flex-layout:为Angular应用程序提供HTML UI布局; 使用Flexbox和响应式API

    入门首先从npm安装Angular Layout库npm i -s @angular/flex-layout @angular/cdk 接下来,您需要在应用程序模块中导入Layout模块。 app.module.ts import { FlexLayoutModule } from '@angular/flex-layout' ;...@ ...

    flex3的cookbook书籍完整版dpf(包含目录)

    编译和部署使用RSL的Flex应用程序 25.6节. 在Flex Builder调试中创建和监视表达式 25.7节. 在Flex Builder中安装Ant窗口 25.8节. 为自动通用任务创建一个Ant构建文件 25.9节. 使用mxmlc和Ant编译Flex应用程序 25.10...

    Python的GUI开发工具Flexx.zip

    Flexx 是一个纯 Python 工具包,用来创建图形化界面应用程序。其使用 Web 技术进行界面的渲染。你可以用 Flexx 来创建桌面应用,同时也可以导出一个应用到独立的 HTML 文档。因为使用纯 Python 开发,所以 Flexx 是...

    Flexbox-mixins

    Flexbox-mixins 在 Web 应用程序中使用 CSS Flex 框模型时,这些混合是我开始的地方。 我希望随着我使用 flex 开发更多应用程序,这些应用程序将演变成一个模块化 mixin 包,用于快速引导 Web 应用程序 UI 布局。

    asp.net知识库

    将 ASP.NET 2.0 应用程序服务配置为使用 SQL Server 2000 或 SQL Server 2005 ASP.NET 2.0 中的数据源控件 使用 ASP.NET 2.0 ObjectDataSource 控件 ASP.NET 2.0 的内部变化 使用SQL Cache Dependency 代替 ...

    ActionScript开发技术大全

    28.4.1应用程序配置 591 28.4.2初始化窗口设置 595 28.4.3图标设置 595 28.4.4关联文??柚?596 28.5小结 597 第29章AIR部分特性介绍 598 29.1AIR本地窗口 598 29.1.1创建与关闭本地窗口 598 29.1.2添加窗体内容 600 ...

    中诺企业网站系统 2.0

    Flex 可使开发人员更好地交付应用程序,这种应用程序使用户可以迅速反应、在不同状态与显示间流畅过渡,并提供毫无中断的连续的工作流。 主体功能列表如下: 系统采用C#语言.net3.5和SQL Server平台开发,系统...

    Angular-VSCode-Angular-TypeScript-Snippets.zip

    Angular-VSCode-Angular-TypeScript-Snippets.zip,Visual Studio代码类型脚本片段(typescript、HTML、...它专注于良好的移动开发、模块化和改进的依赖注入。angular的设计目的是全面解决开发人员的web应用程序工作流。

    Maven权威指南 很精典的学习教程,比ANT更好用

    构建一个打包好的命令行应用程序 5. 一个简单的Web应用 5.1. 介绍 5.1.1. 下载本章样例 5.2. 定义这个简单的Web应用 5.3. 创建这个简单的Web应用 5.4. 配置Jetty插件 5.5. 添加一个简单的Servlet 5.6. ...

    有关单片机电子密码锁

    将程序下载到FLEX10K芯片中,同时在杭州康芯生产的型号为GW48-GK的EDA实验箱上进行硬件验证。经实验验证,该密码锁达到了设计要求。 本文提出的智能密码锁由于采用VHDL 语言设计,用一片FPGA实现,因而体积小...

Global site tag (gtag.js) - Google Analytics