• Flex中的模块


    参考

     

    应用Moduler方式重构应用

    Using the ApplicationDomain class

    加载和卸载模型

    关于flex的module开发

     

     

    Module

    Module加载是Adobe解决Flex系统应用初始化时较大的下载负载而设计的一种折中方案。Module是为自己项目准备的,如果你的项目编译后大小是1.5MB,那么也许在你使用module把项目合理分割以后大小会是 700K + 200K+ 100K+200K+ 200K+200K。为什么后面的模块体积会变小,就是因为公有的类引用没有重复编译到他们之中了。 所以Module是为同一个项目准备的,他们之间有很强的依赖关系,并不是为其他项目提供 "包" 。

     

    Module 实际上是一个预编译的SWF文件。虽然是SWF格式的文件,但是这个文件不能独立运行,并且只能被ModuleLoader加载后才能显示。逻辑上它是一个容器,可以像一般的容器一样包含别的容器,组件,甚至是别的Module模块。根据需要,预编译的Module模块可以被应用加载和卸载。

     

    Flex Builder中创建Module

     

          可以使用<mx:Module>创建Module类;令一种方式采用ModuleManager类在ActionScript中创建Module模块类。在Flex Builder创建Module非常方便,如下图:

     

     



          
          
        

          在编译的时候就会生成一个和mxml文件同名的swf文件。

     

        

     

     

         AS中创建Module

     

     

         如果您编写仅 ActionScript 模块,则可以扩展mx.modules.ModuleBase类。如果 是MXML 文件中的 <mx:Module> 标签编写基于 MXML 的模块,就应该扩展 mx.modules.Module类,它会将其加入到可视化显示列表。

     

     

     

     

     

    Module域

     

     

    通常将模块载入一个子域,那么模块里面的类定义都不是application域的。比如第一个模块载入了类PopUpManager,那么整合Application中,它就成了PopUpManager的拥有者,因为像这种manager都是单例的,如果另外一个模块稍后要使用这个PopUpManager,就会引发运行时异常。

     

    解决办法就是确保这些managers,比如PopUpManager and DragManager或者其他一些共享的服务 是在application中定义的,这样就能确保所有模块都能够使用。在main Application中:

     

     

    Java代码 
    1. import mx.managers.PopUpManager;  
    2.   
    3. import mx.managers.DragManager;  
    4.   
    5. private var popUpManager:PopUpManager;  
    6.   
    7. private var dragManager:DragManager;  

     

     

     

     

     

    这项技术同时也应用到组件中,当module第一次使用组件时,将在它自己的域中拥有这些组件的类定义。如果别的module试图使用这些已经被另一个module使用的组件,它的定义将会不能匹配到现存的定义中。因此,为了避免组件的定义不匹配,在主应用程序中创建组件的实例,让所有的module去引用。

     

    但是这个坏处很明显,这些声明莫名其妙,成为了一个"木偶变量",所以在网上找到另一种办法,参见

     

    http://www.blogjava.net/alex0927/archive/2008/11/24/241989.html?opt=admin

     

    在ModuleLoader 的creationComplete方法中加入如下代码,表示将其加载到运行时库

    moduleLoader.applicationDomain = ApplicationDomain.currentDomain;

    对于使用ModuleManager,可以在IModuleInfo的load方法里面指定域。

     

    有关于应用程序域内容存可以参考下面几篇文章:

     

    http://hereson.javaeye.com/blog/192337

     

    http://bufanliu.javaeye.com/blog/200594

     

     

     

     

     

     

     

    ModuleLoader

     

    Flex中的ModuleLoader组件为模块的载入提供和很方便的接口,它是高层的处理Module的API。

     

    可以这种在flex中简单的使用module

     

     

    Java代码 
    1. <mx:ModuleLoader url="MXMLDemoModule.swf"/>  

     

     

     

     

     

    也可以在编程时动态的改变URL,来加载不同的Module。

     

    ModuleLoader其实是一种特殊的导航式容器。和一般导航式容器如ViewStack不同的是,ModuleLoader不必在初始化时携带加载所有的孩子组件。

     

    另外,推荐在moduleloader做切换的时候,加上:moduleLoader.unloadModule再做moduleLoader.loadModule()。Flex确保调用load()方法只有一个对象。

     

     

     

     

     

    ModuleManager

     

    ModuleManager类提供了低层次的处理Module的装载卸载以及事件响应等的变成接口。这种方式比起纯粹的ModuleLoader方式稍微复杂一点,但是ModuleManager提供了比ModuleLoader更加强大的能力来管理Module模块的加载过程。

     

           具体操作可以分成以下几步:

     

    1.通过ModuleManager实例的getModule()方法拿到Module模块的一个索引,索引类型为IModuleInfo。 

     

    2.调用这个索引的load()方法。 

     

    3.利用这个接口的factory属性拿到它相关连的Module工厂,调用此工厂的create()方法,并将返回值强制转换成当前的Module类型。

     

        

         看以下代码:

     

     

     

     

     

    Java代码 
    1.                  private var module:IModuleInfo;  
    2.   
    3. module = ModuleManager.getModule("UserList.swf");  
    4.   
    5. module.addEventListener(  
    6. ModuleEvent.READY,onModuleReadyUseModuleManager);  
    7.   
    8. module.load();  
    9.   
    10. private function onModuleReadyUseModuleManager(event:Event):void{  
    11.   
    12.     var me:ModuleEvent = event as ModuleEvent;    
    13.     userList = me.module.factory.create() as UserList;        
    14.     container.addChild(userList);  
    15.               
    16. }  

     

     

     

     

     

     

     

          在调用create()方法的时候,可以先不加入显示列表,这样就可以先将module载入内存,需要的时候再加入显示列表。

     

     

     

     

     

         加载过程的事件

     

         这个倒不是ModuleManager特有的,ModuleLoader也有,就是setup,ready,unload,progress,error等事件。

     

             Progress事件

     

     

     

     

    Java代码 
    1. protected function onModuleProgress (e:ModuleEvent) : void {  
    2.   
    3.     trace ("ModuleEvent.PROGRESS received: " + e.bytesLoaded + " of " + e.bytesTotal + " loaded.");  
    4.       
    5.        }  

     

     

       主要就是bytesLoadedbytesTotal,分别表示已经加载的字节数和总共的字节数。

     

     

     

     

     

     

    模块与应用之间的访问

     

     

     

     


                

     

     

     

     

          Application访问模块

          用ModuleLoader载入的模块,application可以用child来访问module中的方法。比如在模块中有一个公共的objectMethod方法

    Java代码 
    1. s = (m1.child as loaderModule).objectMethod();  

     

    如果使用ModuleManager,那么可以向下面这样:

    Java代码 
    1. public var sm:Object=moduleInfo.factory.create() as loaderModule;  
    2.   
    3. s = sm. objectMethod;  

     

     

         模块访问Application

          主要是使用parentApplication 属性:

    Java代码 
    1. // testProperty可以是application的一个属性或者方法,当然module的可移植性几乎就没有了  
    2.   
    3. var aa:Object=this.parentApplication.testProperty;  

     

     

    模块访问模块

          有两个模块,可以通过Application来访问:

     

    Java代码 
    1. <mx:ModuleLoader url="InterModule1.swf" id="m1"/>  
    2.   
    3. <mx:ModuleLoader url="InterModule2.swf" id="m2"/>  
    4.   
    5.   
    6. s = parentApplication.m1.child. objectMethod ();  

     

     

        给ModuleLoader传递参数

     

         采用给url传递参数的方式,下面的是载入module的url

     

          

    Java代码 
    1. var s:String = "QueryStringModule.swf?" + "firstName=" +ti1.text + "&lastName=" + ti2.text;  

     

     

          在模块中

     

     

    Java代码 
    1.       var myPattern:RegExp = /.*\?/;  
    2.       var s:String = this.loaderInfo.url.toString();  
    3.       s = s.replace(myPattern, "");  
    4.   
    5.       var params:Array = s.split("&");  
    6.       var keyStr:String;  
    7.       var valueStr:String;  
    8.       var paramObj:Object = params;  
    9.           
    10.    for (keyStr in paramObj) {  
    11. valueStr = String(paramObj[keyStr]);  
    12. ta1.text += keyStr + ":" + valueStr + "\n";  
    13.     }  
    14.           
    15.     for (var i:int = 0; i < params.length; i++) {  
    16. var tempA:Array = params[i].split("=");  
    17. if (tempA[0] == "firstName") {  
    18.       o.firstName = tempA[1];  
    19. }  
    20. if (tempA[0] == "lastName") {  
    21.        o.lastName = tempA[1];  
    22. }  
    23.       }  
    24.   
    25.       if (StringUtil.trim(o.firstName) != "" &&  StringUtil.trim(o.lastName) != "") {  
    26. salutation = "Welcome " +o.firstName + " " + o.lastName + "!";  
    27.       } else {  
    28. salutation = "Full name not entered."  
    29.       }  

     

     

     

    利用接口避免耦合

     

          我们可以定义一个ActionScript接口,Module模块对象实现了这个接口中定义的方法和属性,那么主应用Application就可以访问这个接口中定义的属性和方法。接口中定义了Module模块对象和主应用Application需要共享的数据和方法,是两者间共同的一个契约,同时也实现了接口和实现的分离,达到了松耦合的目的。

    接口

    Java代码 
    1. package{  
    2.   
    3.   
    4. import flash.events.IEventDispatcher;  
    5.   
    6.   
    7.     public interface IModuleInterface extends IEventDispatcher {  
    8.   
    9.          function getModuleName():String;  
    10.   
    11.          function setAdjusterID(s:String):void;  
    12.   
    13.          function setBackgroundColor(n:Number):void;  
    14.   
    15.    }  
    16.   
    17.   
    18. }  

     

     

    模块文件IModuleInterface

    Java代码 
    1. <?xml version="1.0"?>  
    2.   
    3. <!-- modules/interfaceexample/AutoInsurance.mxml -->  
    4.   
    5. <mx:Module xmlns:mx="http://www.adobe.com/2006/mxml" width="100%"  
    6.   
    7. height="100%" implements="IModuleInterface">  
    8.   
    9.   
    10. <mx:Panel id="p1" title="Auto Insurance" width="100%" height="100%" backgroundColor="{bgcolor}">   
    11.   
    12. <mx:Label id="myLabel" text="ID: {adjuster}"/>  
    13.   
    14. </mx:Panel>  
    15.   
    16.   
    17. <mx:Script>  
    18.   
    19.   
    20. <![CDATA[  
    21.   
    22. [Bindable]  
    23.   
    24. private var adjuster:String;  
    25.   
    26. [Bindable]  
    27.   
    28. private var bgcolor:Number;  
    29.   
    30.   
    31. public function setAdjusterID(s:String):void {  
    32.   
    33. adjuster = s;  
    34.   
    35. }  
    36.   
    37. public function setBackgroundColor(n:Number):void {  
    38.   
    39. bgcolor = n;  
    40.   
    41. }  
    42.   
    43. public function getModuleName():String {  
    44.   
    45. return "Auto Insurance";  
    46.   
    47. }  
    48.   
    49. ]]>  
    50.   
    51. </mx:Script>  
    52.   
    53. </mx:Module>  

     

     

        Application中

     

    Java代码 
    1. var ichild:* = mod.child as IModuleInterface;  
    2.   
    3.   
    4. if (mod.child != null) {  
    5.   
    6.   
    7.     ichild.setAdjusterID(myId.text);  
    8.   
    9.    ichild.setBackgroundColor(myColor.selectedColor);  
    10.   
    11.   
    12. }  

      

  • 相关阅读:
    HDU 1078 FatMouse and Cheese (简单DP)
    HDU 1052 Tian Ji The Horse Racing (贪心)
    HDU 4432 Sum of divisors 第37届ACM/ICPC天津现场赛B题 (简单题)
    HDU 1079 Calendar Game (博弈)
    HDU 4438 Hunters 第37届ACM/ICPC 天津赛区现场赛H题(超级水的题目)
    php级联
    C++运算符重载
    C++循环语句
    C++类复制构造函数
    C++ struct,union和enum
  • 原文地址:https://www.cnblogs.com/sunwei2012/p/1912817.html
Copyright © 2020-2023  润新知