Flex中ModuleManager的一个bug
2011-11-03 20:27
281 查看
估且认为它是一个bug吧,因为到目前为止还是没想明白造成问题的原因。
在相对较为复杂或是多人协作的flex项目开发中,使用module进行开发是很平常的事情,而module的加载一般常用的有两种方法:
1、使用ModuleLoader加载器;
2、使用ModuleManager进行加载;
使用ModuleLoader进行加载:
[/code]
使用ModuleManager进行加载:
ModuleManager类负责管理加载的模块,当将模块的url传递到public的ModuleManager.getModule方法中时,则该模块位置就添加到被管理模块的列表中,并返回一个mx.modules.IModuleInfo的实例。
ModuleInfo对象负责加载swf文件,并被封装成一个实现了IModuleInfo接口的代理类,由ModuleManager.getModule方法返回,可以监听代理类上的状态事件,比如:ready、error、setup、progress事件等.
table {border-collapse:collapse; border:1px solid #ccc;}
td,th {border:1px solid #ccc; padding:8px;}
caption {text-align:left; padding-bottom:10px;}
mx.events.ModuleEvent类
但我在写实际的demo示例时,发现一个问题,如果没有事先声明IModuleInfo类的实例,在使用上面方面加载模块时,第一次加载不会调用任何的方法。完成的示例代码如下:
[/code]
在上面例子中,事先已经声明过了一个IModuleInfo类的实例,在加载时如果使用该实例进行加载则一切正常,如果不使用已经被声明过的实例加载,则第一次加载时,不会有任何的反应,但使用ModuleLoader是没有此问题的,所以我只能认为这是一个bug了
示例项目工程的目录很简单:
如果想使用ModuleManager加载模块,保险的方式就是先声明一个IModuleInfo类的实例,然后使用该实例去加载模块。两种加载模块的优先方法相比,一般更为常用的是第二种,因为可以预加载模块,比较容易按不同的需求来控制模块。
在相对较为复杂或是多人协作的flex项目开发中,使用module进行开发是很平常的事情,而module的加载一般常用的有两种方法:
1、使用ModuleLoader加载器;
2、使用ModuleManager进行加载;
使用ModuleLoader进行加载:
[code]<mx:ModuleLoader id="moduleLoader" right="10" top="10"/> // private function loadModule(url:String):void { if (moduleLoader.url) { moduleLoader.unloadModule(); } moduleLoader.url = url; }
[/code]
使用ModuleManager进行加载:
private function load(url:String):void { var tempModuleInfo:IModuleInfo = ModuleManager.getModule(url); tempModuleInfo.addEventListener(ModuleEvent.READY, onReady); tempModuleInfo.addEventListener(ModuleEvent.PROGRESS, onProgress); tempModuleInfo.addEventListener(ModuleEvent.ERROR, onError); tempModuleInfo.addEventListener(ModuleEvent.SETUP, onSetup); tempModuleInfo.load(ApplicationDomain.currentDomain); } //... private function onReady(evt:ModuleEvent):void { var tempModuleInfo:IModuleInfo = evt.target as IModuleInfo; container.addChild(tempModuleInfo.factory.create() as DisplayObject); }
ModuleManager类负责管理加载的模块,当将模块的url传递到public的ModuleManager.getModule方法中时,则该模块位置就添加到被管理模块的列表中,并返回一个mx.modules.IModuleInfo的实例。
ModuleInfo对象负责加载swf文件,并被封装成一个实现了IModuleInfo接口的代理类,由ModuleManager.getModule方法返回,可以监听代理类上的状态事件,比如:ready、error、setup、progress事件等.
table {border-collapse:collapse; border:1px solid #ccc;}
td,th {border:1px solid #ccc; padding:8px;}
caption {text-align:left; padding-bottom:10px;}
常量 | 字符串值 | 描述 |
---|---|---|
PROGRESS | "progress" | 加载模块时被调度。可以用这个事件访问被加载模块的bytesLoaded和bytesTotal属性 |
SETUP | "setup" | 当已加载了足够的模块内容时被调度 |
READY | "ready" | 当模块完成加载时被调度 |
UNLOAD | "unload" | 当卸载模块时被调度 |
ERROR | "error" | 当模块下载过程中出错时被调度 |
但我在写实际的demo示例时,发现一个问题,如果没有事先声明IModuleInfo类的实例,在使用上面方面加载模块时,第一次加载不会调用任何的方法。完成的示例代码如下:
[code]<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" minWidth="955" minHeight="600" creationComplete="inited()"> <mx:Script> <![CDATA[ import mx.events.ModuleEvent; import mx.modules.IModuleInfo; import mx.modules.ModuleManager; private var module_1_url:String = "com/modules/OneModule.swf"; private var module_2_url:String = "com/modules/TwoModule.swf"; private var _moduleInfo:IModuleInfo; private function inited():void { } private function loadModule(type:Number):void { var url:String; if (type === 1) { url = module_1_url; } else { url = module_2_url; } var tempModuleInfo:IModuleInfo = ModuleManager.getModule(url); //注释或使用下面一行,运行查看不同的效果 _moduleInfo = tempModuleInfo; tempModuleInfo.addEventListener(ModuleEvent.READY, onReady); tempModuleInfo.addEventListener(ModuleEvent.PROGRESS, onProgress); tempModuleInfo.addEventListener(ModuleEvent.ERROR, onError); tempModuleInfo.addEventListener(ModuleEvent.SETUP, onSetup); tempModuleInfo.load(ApplicationDomain.currentDomain); } private function onSetup(evt:ModuleEvent):void { } private function onProgress(evt:ModuleEvent):void { msg.htmlText = "正在加载:" + Math.floor(evt.bytesLoaded / evt.bytesTotal).toString() + "%"; } private function onReady(evt:ModuleEvent):void { var moduleInfo:IModuleInfo = evt.target as IModuleInfo; moduleInfo.removeEventListener(ModuleEvent.PROGRESS, onProgress); moduleInfo.removeEventListener(ModuleEvent.READY, onReady); moduleInfo.removeEventListener(ModuleEvent.ERROR, onError); msg.htmlText = "模块加载完成"; moduleCanvas.addChild(moduleInfo.factory.create() as DisplayObject); } private function onError(evt:ModuleEvent):void { msg.htmlText = "模块加载出错!"; } private function useLoader():void { if (moduleLoader.url) { moduleLoader.unloadModule(); } moduleLoader.url = module_1_url; } ]]> </mx:Script> <mx:Text id="msg" /> <mx:HBox width="400" horizontalGap="10" y="50" x="50"> <mx:Button label="动态加载模块一" click="loadModule(1)" /> <mx:Button label="动态加载模块二" click="loadModule(2)" /> <mx:Spacer width="50" /> <mx:Button label="使用加载器" click="useLoader()" /> </mx:HBox> <mx:ModuleLoader id="moduleLoader" right="10" top="10"/> <mx:Tile horizontalGap="10" width="100%" id="moduleCanvas" y="100" /> </mx:Application>
[/code]
在上面例子中,事先已经声明过了一个IModuleInfo类的实例,在加载时如果使用该实例进行加载则一切正常,如果不使用已经被声明过的实例加载,则第一次加载时,不会有任何的反应,但使用ModuleLoader是没有此问题的,所以我只能认为这是一个bug了
示例项目工程的目录很简单:
如果想使用ModuleManager加载模块,保险的方式就是先声明一个IModuleInfo类的实例,然后使用该实例去加载模块。两种加载模块的优先方法相比,一般更为常用的是第二种,因为可以预加载模块,比较容易按不同的需求来控制模块。
相关文章推荐
- Flex 3 Module的一个诡异bug
- [Flex]FileReference的一个bug!?
- [Flex]FileReference的一个bug!?
- [Flex]FileReference的一个bug!?
- FLEX 4.5 DateChooser放入PopUpAnchor后的一个 2B bug
- 应该是Angular2的一个bug?
- VC6调试版本C运行库内存申请的一个bug
- C++标准库的一个有趣的小bug
- windows PSAPI.h 的一个BUG ?
- 编程经验:一个由windows.h&&winbase.h引起的bug~
- 关于vs2008sp1的一个BUG
- VC7.1 编译器的一个不大不小的bug
- 一个已知的Andorid Bug
- document.elements.length的一个bug
- 一个bug引发的“血案”
- 修复一个吉日嘎拉MSSQL数据库版中的分页存储过程bug
- JUnit4的一个bug
- FireFox的一个bug
- FLASH PLAYER 9.0的一个BUG getURL(url,"_self","POST") 点击无效
- 偶然间碰到了一个vc的一个bug,太有意思了