Flex中ModuleManager的一个bug

估且认为它是一个bug吧,因为到目前为止还是没想明白造成问题的原因。

在相对较为复杂或是多人协作的flex项目开发中,使用module进行开发是很平常的事情,而module的加载一般常用的有两种方法:

1、使用ModuleLoader加载器;

2、使用ModuleManager进行加载;

使用ModuleLoader进行加载:

<mx:ModuleLoader id="moduleLoader" right="10" top="10"/>

//
private function loadModule(url:String):void
{
    if (moduleLoader.url)
    {
        moduleLoader.unloadModule();    
    }
    
    moduleLoader.url = url;
}

使用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类的实例,在使用上面方面加载模块时,第一次加载不会调用任何的方法。完成的示例代码如下:

<?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>

在上面例子中,事先已经声明过了一个IModuleInfo类的实例,在加载时如果使用该实例进行加载则一切正常,如果不使用已经被声明过的实例加载,则第一次加载时,不会有任何的反应,但使用ModuleLoader是没有此问题的,所以我只能认为这是一个bug了

示例项目工程的目录很简单:

如果想使用ModuleManager加载模块,保险的方式就是先声明一个IModuleInfo类的实例,然后使用该实例去加载模块。两种加载模块的优先方法相比,一般更为常用的是第二种,因为可以预加载模块,比较容易按不同的需求来控制模块。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏木子昭的博客

webpack手动配置React开发环境

1643
来自专栏软件开发

Node.js开发Web后台服务

一、简介 Node.js 是一个基于Google Chrome V8 引擎的 JavaScript 运行环境。Node.js 使用了一个事件驱动、非阻塞式 I/...

1.4K9
来自专栏前端

前后端分离ueditor富文本编辑器的使用-Java版本

最近在写一个自己的后台管理系统(主要是写着玩的,用来熟悉后端java的知识,目前只是会简单的写点接口),想在项目中编写一个发布新闻文章的功能,想到了使用百度的u...

1.5K10
来自专栏飞雪无情的博客

Go语言实战笔记(二十一)| Go 单元测试

相信我们做程序员的,对单元测试都不陌生。单元测试一般是用来测试我们的代码逻辑有没有问题,有没有按照我们期望的运行,以保证代码质量。

1522
来自专栏大史住在大前端

javascript基础修炼(6)——前端路由的基本原理

现代前端开发中最流行的页面模型,莫过于SPA单页应用架构。单页面应用指的是应用只有一个主页面,通过动态替换DOM内容并同步修改url地址,来模拟多页应用的效果,...

1593
来自专栏卡少编程之旅

类webpack模板的多页Vue项目模板

6866
来自专栏Ryan Miao

Hello ReactJS

前言 React学习前先搭好环境,官网的例子看着比较分散。结合webpack就可以体验完整的es6开发流程了。 源码:https://github.com/R...

2577
来自专栏hbbliyong

SpringBoot之前端文件管理

WebJars能使Maven的依赖管理支持OSS的JavaScript库/CSS库,比如jQuery、Bootstrap等。  (1)添加js或者css库 ...

3716
来自专栏为数不多的Android技巧

简化markdown写作中的贴图流程

这么复杂的流程,让人简直没有了插入图片的欲望;但是大量的文字没有图片,必然让人疲惫;

1465
来自专栏JavaEdge

命令模式

3197

扫码关注云+社区

领取腾讯云代金券