加载module时传递参数

自从 flex3 开始就加入了 module 。在工程中使用 module 可以减少生成的 swf 的大小,或者可以动态添加系统的功能。使用起来非常方便,相对于使用 SwfLoader ModuleLoader 用起来更加方便。

在使用 ModuleLoader Module 时总会遇到在加载 Module 时传递参数的情况,前几天“一定搞定啥”老兄问了我这个问题,当时我给了他一个思路,就是自定义一个可以传递参数的事件,在 Module 中进行这个事件的监听,需要传递参数时使用 ModuleLoader.child.dispatchEvent(event) 这种方法来进行参数传递。当时我试了一下还是挺好用的。但是有一个前提就是 Module 必须是已经加载完成并且初始化完成之后。如果 Module 是动态加载的,需要在初始化完成之后就得到参数就比较困难了。

起初我想在 ModuleLoader Ready 事件中向 child 派发事件,以为 Ready 事件触发时应该是 Module 已经加载成功之后了。遗憾的是这种方法并不好用,我想原因应该是这样:

Ready 事件发生时, Module 是加载成功了,但是加载成功并不意味着初始化完成,事实证明此时 Module swf 还未初始化完成,用 setTimeout 函数测试发现 Ready 事件发生之后大约一秒钟之后 Module 才会响应外部派发的事件,这个时间会因为处理器的处理速度不同而不同,所以用 setTimeout 只是一个最烂的点子。

后来我有一个思路,就是在 Module 初始化成功后,告诉 ModuleLoader 我已经初始化成功了,把参数传给我吧,于是 ModuleLoader 就把参数传给 Module 。很简单的一个对话模型,不过在原有控件基础上实现就很困难,所以需要扩展一下 Module Moduleloader ,把需要对话的机制加进去才可以。

其工作原理图:

加载module时传递参数_第1张图片

首先自定义一个 Event 类,这个类里添加一个成员变量来传递参数:

 

package event { import flash.events.Event; public class MyEvent extends Event { public var str:String = ""; public function MyEvent(type:String, bubbles:Boolean=false, cancelable:Boolean=false) { super(type, bubbles, cancelable); } } }

然后扩展 Module ,创建一个 Module 的子类命名为 MyModule ,在这个类中声明一个事件,派发时机是 Module CREATION_COMPLETE 事件发生后,目的是便于 ModuleLoader 监听这个事件,实现对话的第一步。另外在 Module 的构造函数中注册一个对 MyEvent 事件的 Listener 来监听参数传递事件。

代码如下:

package comp { [Event(name="ready0", type="mx.events.ModuleEvent")] import event.MyEvent; import mx.controls.Alert; import mx.events.FlexEvent; import mx.events.ModuleEvent; import mx.modules.Module; public class MyModule extends Module { public function MyModule() { super(); this.addEventListener(FlexEvent.CREATION_COMPLETE, init); //监听参数传递事件 this.addEventListener("MyEvent",myEventAction); } private function init(e:FlexEvent):void { //在CREATION_COMPLETE事件发生后派发完成事件 this.dispatchEvent(new ModuleEvent("ready0")); } //参数传递事件监听函数 protected function myEventAction(myevent:MyEvent):void { } } }

最后扩展一下 ModuleLoader ,定义一个 Moduleloader 的子类 MyModuleloader 。在 Moduleloader READY 事件中为 Moduleloader child 注册一个 ready0 事件的监听,并且在 UNLOAD 的事件中去掉监听。添加了一个新函数 loadModuleParam ,这个函数可以带一个字符串类型的参数。

<?xml version="1.0" encoding="utf-8"?> <mx:ModuleLoader xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" width="400" height="300" ready="moduleLoader_ReadyHandler(event)" unload="moduleLoader_unloadHandler(event)"> <fx:Declarations> <!-- Place non-visual elements (e.g., services, value objects) here --> </fx:Declarations> <fx:Script> <!--[CDATA[ import event.MyEvent; import mx.events.ModuleEvent; private var msg:String = ""; protected function moduleLoader_ReadyHandler(event:ModuleEvent):void { var mymd:MyModule = child as MyModule; mymd.addEventListener("ready0", child_ReadyHandler); } private function child_ReadyHandler(event:ModuleEvent):void { var eve:MyEvent = new MyEvent("MyEvent"); eve.str = msg; child.dispatchEvent(eve); } protected function moduleLoader_unloadHandler(event:ModuleEvent):void { var mymd:MyModule = child as MyModule; mymd.removeEventListener("ready", child_ReadyHandler); } public function loadModuleParam(url:String = null, parameter:String = ""):void { msg = parameter; super.loadModule(url); } ]]--> </fx:Script> </mx:ModuleLoader>

在使用时,所有的 Module 必须继承与 MyModule ,画面上的控件也要使用 MyModuleloader ,两者配合使用才可以。加载 Module 是必须使用 loadModuleParam 函数。

<comp:MyModuleLoader id="ml" x="39" y="32" width="410" height="196"/> protected function button2_clickHandler(event:MouseEvent):void { ml.unloadModule(); ml.loadModuleParam("su/SuMd2.swf","wwwwwwww"); }

MyModule 的子类如果要得到参数还必须覆盖一下父类中的 myEventAction 函数:

protected override function myEventAction(myevent:MyEvent):void { text1.text = myevent.str; }

这样就 OK 了。测试了一下还是很好用的。

这个例子使用 FlashBuilder4 完成的,使用时请注意版本。

可以到http://to9m.download.csdn.net/去下载源代码。

你可能感兴趣的:(function,String,Module,扩展,import,library)