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代码 复制代码 收藏代码
import mx.managers.PopUpManager;       import mx.managers.DragManager;       private var popUpManager:PopUpManager;       private var dragManager:DragManager;  
import mx.managers.PopUpManager;

import mx.managers.DragManager;

private var popUpManager:PopUpManager;

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代码 复制代码 收藏代码
<mx:ModuleLoader url="MXMLDemoModule.swf"/>  
<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代码 复制代码 收藏代码
                 private var module:IModuleInfo;       module = ModuleManager.getModule("UserList.swf");       module.addEventListener(    ModuleEvent.READY,onModuleReadyUseModuleManager);       module.load();       private function onModuleReadyUseModuleManager(event:Event):void{           var me:ModuleEvent = event as ModuleEvent;          userList = me.module.factory.create() as UserList;              container.addChild(userList);                    }  
                  private var module:IModuleInfo;

	module = ModuleManager.getModule("UserList.swf");
	
	module.addEventListener(
	ModuleEvent.READY,onModuleReadyUseModuleManager);
	
	module.load();

	private function onModuleReadyUseModuleManager(event:Event):void{

		var me:ModuleEvent = event as ModuleEvent;	
		userList = me.module.factory.create() as UserList;		
		container.addChild(userList);
				
	}

 

 

 

 

 

 

 

 

 

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

 

 

 

 

 

 

 

     加载过程的事件

 

 

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

 

 

         Progress事件

 

 

 

 

 

Java代码 复制代码 收藏代码
protected function onModuleProgress (e:ModuleEvent) : void {           trace ("ModuleEvent.PROGRESS received: " + e.bytesLoaded + " of " + e.bytesTotal + " loaded.");                   }  
protected function onModuleProgress (e:ModuleEvent) : void {

	trace ("ModuleEvent.PROGRESS received: " + e.bytesLoaded + " of " + e.bytesTotal + " loaded.");
	
       }


 

 

 

 

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

 

 

 

 

 

 

 

 

模块与应用之间的访问

 

 

 

 

 

 


           

 

 

 

 

 

      Application访问模块

 

 

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

 

 

 

Java代码 复制代码 收藏代码
s = (m1.child as loaderModule).objectMethod();  
s = (m1.child as loaderModule).objectMethod();

 

 

 

 

 

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

 

 

 

Java代码 复制代码 收藏代码
public var sm:Object=moduleInfo.factory.create() as loaderModule;       s = sm. objectMethod;  
public var sm:Object=moduleInfo.factory.create() as loaderModule;

s = sm. objectMethod;


 

 

 

 

 

     模块访问Application

 

 

      主要是使用parentApplication 属性:

 

 

 

 

 

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

var aa:Object=this.parentApplication.testProperty;

 

 

 

 

模块访问模块

 

 

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

 

 

 

 

Java代码 复制代码 收藏代码
<mx:ModuleLoader url="InterModule1.swf" id="m1"/>       <mx:ModuleLoader url="InterModule2.swf" id="m2"/>          s = parentApplication.m1.child. objectMethod ();  
<mx:ModuleLoader url="InterModule1.swf" id="m1"/>

<mx:ModuleLoader url="InterModule2.swf" id="m2"/>


s = parentApplication.m1.child. objectMethod ();



 

 

    给ModuleLoader传递参数

 

 

 

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

 

      

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

 

 

      在模块中

 

 

 

 

Java代码 复制代码 收藏代码
      var myPattern:RegExp = /.*/?/;          var s:String = this.loaderInfo.url.toString();          s = s.replace(myPattern, "");             var params:Array = s.split("&");          var keyStr:String;          var valueStr:String;          var paramObj:Object = params;                   for (keyStr in paramObj) {    valueStr = String(paramObj[keyStr]);    ta1.text += keyStr + ":" + valueStr + "/n";        }                    for (var i:int = 0; i < params.length; i++) {    var tempA:Array = params[i].split("=");    if (tempA[0] == "firstName") {          o.firstName = tempA[1];    }    if (tempA[0] == "lastName") {           o.lastName = tempA[1];    }          }             if (StringUtil.trim(o.firstName) != "" &&  StringUtil.trim(o.lastName) != "") {    salutation = "Welcome " +o.firstName + " " + o.lastName + "!";          } else {    salutation = "Full name not entered."         }  
       var myPattern:RegExp = /.*/?/;
       var s:String = this.loaderInfo.url.toString();
       s = s.replace(myPattern, "");
	
       var params:Array = s.split("&");
       var keyStr:String;
       var valueStr:String;
       var paramObj:Object = params;
			
    for (keyStr in paramObj) {
	valueStr = String(paramObj[keyStr]);
	ta1.text += keyStr + ":" + valueStr + "/n";
     }
			
     for (var i:int = 0; i < params.length; i++) {
	var tempA:Array = params[i].split("=");
	if (tempA[0] == "firstName") {
	      o.firstName = tempA[1];
	}
	if (tempA[0] == "lastName") {
	       o.lastName = tempA[1];
	}
       }

       if (StringUtil.trim(o.firstName) != "" &&  StringUtil.trim(o.lastName) != "") {
	salutation = "Welcome " +o.firstName + " " + o.lastName + "!";
       } else {
	salutation = "Full name not entered."
       }


 

 

 

 

 

利用接口避免耦合

 

 

 

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

 

 

接口

 

 

 

Java代码 复制代码 收藏代码
package{          import flash.events.IEventDispatcher;              public interface IModuleInterface extends IEventDispatcher {                function getModuleName():String;                function setAdjusterID(s:String):void;                function setBackgroundColor(n:Number):void;          }          }  
package{


import flash.events.IEventDispatcher;


    public interface IModuleInterface extends IEventDispatcher {

         function getModuleName():String;

         function setAdjusterID(s:String):void;

         function setBackgroundColor(n:Number):void;

   }


}



 

 

 

 

模块文件IModuleInterface

 

 

 

Java代码 复制代码 收藏代码
<?xml version="1.0"?>       <!-- modules/interfaceexample/AutoInsurance.mxml -->       <mx:Module xmlns:mx="http://www.adobe.com/2006/mxml" width="100%"      height="100%" implements="IModuleInterface">          <mx:Panel id="p1" title="Auto Insurance" width="100%" height="100%" backgroundColor="{bgcolor}">        <mx:Label id="myLabel" text="ID: {adjuster}"/>       </mx:Panel>          <mx:Script>          <![CDATA[       [Bindable]       private var adjuster:String;       [Bindable]       private var bgcolor:Number;          public function setAdjusterID(s:String):void {       adjuster = s;       }       public function setBackgroundColor(n:Number):void {       bgcolor = n;       }       public function getModuleName():String {       return "Auto Insurance";       }       ]]>       </mx:Script>       </mx:Module>  
<?xml version="1.0"?>

<!-- modules/interfaceexample/AutoInsurance.mxml -->

<mx:Module xmlns:mx="http://www.adobe.com/2006/mxml" width="100%"

height="100%" implements="IModuleInterface">


<mx:Panel id="p1" title="Auto Insurance" width="100%" height="100%" backgroundColor="{bgcolor}"> 

<mx:Label id="myLabel" text="ID: {adjuster}"/>

</mx:Panel>


<mx:Script>


<![CDATA[

[Bindable]

private var adjuster:String;

[Bindable]

private var bgcolor:Number;


public function setAdjusterID(s:String):void {

adjuster = s;

}

public function setBackgroundColor(n:Number):void {

bgcolor = n;

}

public function getModuleName():String {

return "Auto Insurance";

}

]]>

</mx:Script>

</mx:Module>


 

 

 

 

 

 

 

 

 

    Application中

 

 

 

Java代码 复制代码 收藏代码
var ichild:* = mod.child as IModuleInterface;          if (mod.child != null) {              ichild.setAdjusterID(myId.text);          ichild.setBackgroundColor(myColor.selectedColor);          }  

转载于:https://www.cnblogs.com/JPAORM/archive/2011/03/16/2509831.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值