`
saboo
  • 浏览: 73403 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论
阅读更多

主要参考书目: 
《ADOBE FLEX3 DEVELOPER GUIDE》 
《Flex.3.Language.Reference.cn.chm》 
《FLEX3 COOKBOOK》 

建议阅读本文档时,参考附件中源码FlexModule(已在FLEX BUILDER3+FLEX SDK3.2下编译通过)。 
相关Module网址 :  http://www.iteye.com/topic/297813
一、Module使用背景
Module是Adobe为解决Flex应用初始化时较大的下载负载问题而设计的一种折中方案。将主Application合理分割为多个Module后,配合延迟加载策略,就可以保证主Application在初始化只加载必要的资源从而减少等待时间。未被访问的Module默认将不被加载,这样在首次访问它们时会需要额外的等待时间,当然我们也可以在监听主Application加载完毕事件中将这些Module提前载入或者直接取消使用延迟加载策略以保证Module的响应时间。 
二、Module相关类和接口简介 
与Module相关的类和接口如下: 
(1)mx.modules.Module->LayoutContainer->Container->UIComponent 
(2)mx.modules.ModuleBase->EventDispatcher->Object 
(3)mx.modules.ModuleLoader->VBox->Box->Container->UIComponent 
(4)mx.modules.ModuleManager->Object 
(5)mx.modules.IModuleInfo->IEventDispatcher 
(6)mx.event.ModuleEvent->ProgressEvent->Event->Object 
(7)mx.core.IFlexModuleFactory 
1、Module和ModuleBase 
Module类是一个容器,继承自FlexSprite,引入了一些框架代码,而ModuleBase类则继承自EventDispatcher。因此,如果我们的Module需要可视化元素,则扩展Module;反之则扩展ModuleBase。ModuleBase由于不依赖任何框架代码,生成的模块体积会更小。 
例如一个带有可供用户输入信息的输入框Module: 
//FlexModule/AsContactList.as 
package 

import mx.containers.Form; 
import mx.containers.FormItem; 
import mx.controls.TextInput; 
import mx.modules.Module; 
public class ASContactList extends Module 

private var _form:Form; 
private var _firstNameItem:FormItem; 
private var _lastNameItem:FormItem; 
public function ASContactList() 

super (); 
this.percentWidth = 100; 
this.percentHeight = 100; 

override protected function createChildren():void 

super.createChildren(); 
_form = new Form(); 
_firstNameItem = createInputItem( "FirstName:"); 
_lastNameItem = createInputItem( "LastName:"); 
_form.addChild( _firstNameItem ); 
_form.addChild( _lastNameItem ); 
addChild( _form ); 

private function createInputItem( label:String ):FormItem 

var item:FormItem = new FormItem(); 
item.label = label; 
item.addChild( new TextInput() ); 
return item; 



例如一个含有greet,welcomeeBack方法的ModuleBase: 
//FlexModule/EntryStateModule.as 
package 

import mx.modules.ModuleBase; 
public class EntryStateModule extends ModuleBase 

public function EntryStateModule() 



public function greet( first:String, last:String ):String 

return "Hello,"+ first + " "+ last + "."; 

public function welcomeBack(first:String,last:String):String 

return "Nice to see you again,"+ first + "."; 



2、ModuleLoader 
ModuleLoader是一个可视化的容器类,可动态加载或卸载扩展自Module或ModuleBase的SWF。其功能类似于mx.controls.SWFLoader组件,不同之处是被载入的SWF需要实现IFlexModuleFactory接口,这样做的目的是为了允许应用程序在运行期间动态载入模块化SWF而不需要在主应用程序中实现此接口,更多关于IFlexModuleFactory的内容请参见文中其它相关部分(在本文第六节 给Module减肥部分中,你可以看到一个继承自Sprite但却很莫名地要实现IFlexModuleFactory接口的“类Module”组件,其原因就在于此)。 
ModuleLoader的url属性被指定或改变时,就会调用loadModule方法加载Module,但是当url=" "时则会调用unloadModule卸载Module。另外,在调用unloadModule方法时,ModuleLoader只是将相应Module的引用置为null释放内存,url属性值并未改变。强烈建议在使用moduleloader做切换时,先调用unloadModule()以确保调用loadModule()方法时只有一个对象。 
ModuleLoader的事件如下: 
(1)error 
下载模块出错时调度。 
(2)loading 
ModuleLoader 开始加载URL时调度 
(3)progress 
下载模块的过程中调度。下载进程期间定期调度此模块。 
(4)ready 
模块完成下载时调度。 
(5)setup 
已下载了足够的模块内容,您可以获得有关模块的信息时调度。 
(6)unload 
卸载模块时调度。 
(7)urlChanged 
给ModuleLoader 新的URL时调度。 
如下展示了一个自定义的ModuleLoader,分别对这七个事件进行了监听。值得一提的是,ModuleLoader对象实例可以直接作为ProgressBar的source属性值被使用。 
<?xml version="1.0" encoding="utf-8"?> 
<!--FlexModule/CustomModuleLoader.mxml --> 
<mx:ModuleLoader xmlns:mx="http://www.adobe.com/2006/mxml" xmlns="*" creationComplete="init()"> 
  <mx:Script> 
    <![CDATA[ 
    public function init():void { 
        addEventListener("urlChanged", onUrlChanged); 
        addEventListener("loading", onLoading); 
        addEventListener("progress", onProgress); 
        addEventListener("setup", onSetup); 
        addEventListener("ready", onReady); 
        addEventListener("error", onError); 
        addEventListener("unload", onUnload); 

        standin = panel; 
        removeChild(standin);        
    } 
    
    public function onUrlChanged(event:Event):void { 
        if (url == null) { 
            if (contains(standin)) 
                removeChild(standin); 
        } else { 
            if (!contains(standin)) 
                addChild(standin); 
        } 
        progress.indeterminate=true; 
        unload.enabled=false; 
        reload.enabled=false; 
    } 

    public function onLoading(event:Event):void { 
        progress.label="Loading module " + url; 
        if (!contains(standin)) 
            addChild(standin); 

        progress.indeterminate=true; 
        unload.enabled=false; 
        reload.enabled=false; 
    } 
    
    public function onProgress(event:Event):void { 
        progress.label="Loaded %1 of %2 bytes..."; 
        progress.indeterminate=false; 
        unload.enabled=true; 
        reload.enabled=false; 
    } 
    
    public function onSetup(event:Event):void { 
        progress.label="Module " + url + " initialized!"; 
        progress.indeterminate=false; 
        unload.enabled=true; 
        reload.enabled=true; 
    } 
    
    public function onReady(event:Event):void { 
        progress.label="Module " + url + " successfully loaded!"; 
        unload.enabled=true; 
        reload.enabled=true; 

        if (contains(standin)) 
            removeChild(standin); 
    } 
    
    public function onError(event:Event):void { 
        progress.label="Error loading module " + url; 
        unload.enabled=false; 
        reload.enabled=true; 
    } 
    
    public function onUnload(event:Event):void { 
        if (url == null) { 
            if (contains(standin)) 
                removeChild(standin); 
        } else { 
            if (!contains(standin)) 
                addChild(standin); 
        } 
        progress.indeterminate=true; 
        progress.label="Module " + url + " was unloaded!"; 
        unload.enabled=false; 
        reload.enabled=true; 
    } 
    
    public var standin:DisplayObject; 
    ]]> 
  </mx:Script> 

  <mx:Panel id="panel" width="100%"> 
    <mx:ProgressBar width="100%" id="progress" source="{this}"/> 
    <mx:HBox width="100%"> 
      <mx:Button id="unload" 
        label="Unload Module" 
        click="unloadModule()" 
      /> 
      <mx:Button id="reload" 
        label="Reload Module" 
        click="unloadModule();loadModule()" 
      /> 
    </mx:HBox> 
  </mx:Panel> 
</mx:ModuleLoader> 
主Application: 
<?xml version="1.0" encoding="utf-8"?> 
<!--FlexModule/CustomModuleLoaderEventApp.mxml--> 
<mx:Application xmlns="*" xmlns:mx="http://www.adobe.com/2006/mxml"> 
    <mx:Script> 
        <![CDATA[ 
            [Bindable] 
            public var selectedItem:Object; 
        ]]> 
    </mx:Script> 
    <mx:ComboBox 
        width="215" 
        labelField="label" 
        close="selectedItem=ComboBox(event.target).selectedItem" 
    > 
        <mx:dataProvider> 
            <mx:Object label="Select Coverage"/>        
            <mx:Object 
                label="Life Insurance" 
                module="insurancemodules/LifeInsurance.swf" 
            /> 
            <mx:Object 
                label="Auto Insurance" 
                module="insurancemodules/AutoInsurance.swf" 
            />          
            <mx:Object 
                label="Home Insurance" 
                module="insurancemodules/HomeInsurance.swf" 
            /> 
        </mx:dataProvider> 
    </mx:ComboBox> 

    <mx:Panel width="100%" height="100%"> 
        <CustomModuleLoader id="mod" 
            width="100%" 
            url="{selectedItem.module}" 
        /> 
    </mx:Panel> 
    <mx:HBox> 
        <mx:Button label="Unload" click="mod.unloadModule()"/> 
        <mx:Button label="Nullify" click="mod.url = null"/> 
    </mx:HBox>  
</mx:Application> 
上述代码中所使用的Module大致上是相同的,比如AutoInsurance 
<?xml version="1.0" encoding="utf-8"?> 
<!--FlexModule/insurancemodules/AutoInsurance.mxml--> 
<mx:Module xmlns:mx="http://www.adobe.com/2006/mxml" 
    layout="absolute" 
    backgroundColor="#ffffff" 
    width="100%" 
    height="100%" 

    <mx:Label 
        x="147" 
        y="50" 
        text="Auto Insurance" 
        fontSize="28" 
        fontFamily="Myriad Pro" 
    /> 
    <mx:Form left="47" top="136"> 
        <mx:FormHeading label="Coverage"/> 
        <mx:FormItem label="Latte Spillage"> 
            <mx:TextInput id="latte" width="200" /> 
        </mx:FormItem> 
        <mx:FormItem label="Shopping Cart to the Door"> 
            <mx:TextInput id="cart" width="200" /> 
        </mx:FormItem> 
        <mx:FormItem label="Irate Moose"> 
            <mx:TextInput id="moose" width="200" /> 
        </mx:FormItem> 
        <mx:FormItem label="Color Fade"> 
            <mx:ColorPicker /> 
        </mx:FormItem> 
    </mx:Form> 
</mx:Module> 
3、ModuleManager和IModuleInfo 
ModuleManager作为模块的管理类,提供了预先加载模块的能力,它有一个重要方法getModule(url:String):IModuleInfo。 
IModuleInfo是特殊模块句柄的接口,可以查询模块状态、获得模块内部 factory 以及加载或卸载模块。属性如下: 
(1)data:Object 
与给定URL的singleton IModuleInfo关联的用户数据。 
(2)error:Boolean 
如果加载模块期间发生错误,则标志显示为true。ModuleManager调度ModuleEvent.ERROR事件时此标志为true。 
(3)factory:IFlexModuleFactory 
模块中定义的IFlexModuleFactory实现。只有在调用ModuleEvent.SETUP事件(或IModuleInfo.setup()方法返回true)后,它才会显示为非null。此时可以调用IFlexModuleFactory.info()方法。一旦调度ModuleEvent.READY事件(或IModuleInfo.ready()方法返回true),就可以调用IFlexModuleFactory.create()方法。 
(4)loaded:Boolean 
如果已对此模块调用load()方法,则标志显示为true。 
(5)ready:Boolean 
如果可以充分加载模块以获得其关联IFlexModuleFactory实现的句柄以及调用其create()方法,则标志显示为true。 
(6)setup:Boolean 
如果可以充分加载模块以获得其关联IFlexModuleFactory实现的句柄以及调用其info()方法,则标志显示为true。 
(7)url:String 
与此模块关联的URL。URL可以是本地的也可以是远程的(如“MyImageModule.swf”或“http://somedomain.com/modules/MyImageModule.swf”)。如果是远程的,必须在模块域和加载它的应用程序之间建立信任关系。 
IModuleInfo的方法如下: 
(1)load(applicationDomain:ApplicationDomain = null, securityDomain:SecurityDomain = null):void 
请求加载该模块。如果已加载该模块,则调用不起任何作用。否则,会开始加载模块,并在加载过程中调度 progress 事件。applicationDomain指正在其中执行代码的当前应用程序域,securityDomain指当前安全沙箱。 
(2)publish(factory:IFlexModuleFactory):void 
将接口发布到ModuleManager。这允许具有String句柄的factory中存在延迟(或去耦)subscriptions。使用以 publish:// 开始的URL来引用以此方式发布的factory。 
(3)release():void 
将当前的引用释放到模块中。这样不会卸载该模块,除非该模块没有其他打开的引用,并且ModuleManager设置为仅包括限制数目的加载模块。 
(4)unload():void 
卸载模块。如果模块中存在未完成的定义引用,则Flash Player和AIR都不会完全卸载此模块,而是将其作为垃圾回收。 
需要说明的是,Module的swf文件和其他application swf一样,会一直被保存在浏览器的缓存中直至被周期性清除或缓存用尽无法再存入,这样做的好处在一些客户端频繁使用某些swf时尤为明显(在本文第七节 将SWF存入FLASH缓存,而不是浏览器缓存部分中,我们将看到更多相关的知识和应用)。在文首的Module使用背景一节中说到,如果主Apllication使用延迟加载策略,可以通过ModuleManager预先加载模块到浏览器缓存,即使此模块当前尚未被使用。下面是一个监听主Application创建完毕事件,在事件处理中使用IModuleInfo的load方法多线程加载将要使用的模块示例。 
<?xml version="1.0" encoding="utf-8"?> 
<!--FlexModule/PreloadModulesApp.mxml--> 
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" 
creationComplete="preloadModules()"> 
    <mx:Script> 
        <![CDATA[ 
        import mx.events.ModuleEvent; 
        import mx.modules.ModuleManager; 
        import mx.modules.IModuleInfo; 
        
        private function preloadModules():void { 
            // Get a reference to the module's interface. 
            var info:IModuleInfo = ModuleManager.getModule("insurancemodules/LifeInsurance.swf"); 
            info.addEventListener(ModuleEvent.READY, modEventHandler); 
            
            // Load the module into memory. The module will be 
            // displayed when the user navigates to the second 
            // tab of the TabNavigator. 
            info.load(); 
        } 
        
        private function modEventHandler(e:ModuleEvent):void { 
            trace("module event: " + e.type); // "ready" 
        } 
        ]]> 
    </mx:Script> 

    <mx:Panel 
        title="Module Example" 
        height="90%" 
        width="90%" 
        paddingTop="10" 
        paddingLeft="10" 
        paddingRight="10" 
        paddingBottom="10" 
    > 

        <mx:Label width="100%" color="blue" 
            text="Select the tabs to change the panel."/> 

        <mx:TabNavigator id="tn" 
            width="100%" 
            height="100%" 
            creationPolicy="auto" 
        > 
            <mx:VBox id="vb1" label="Default Display Module"> 
                <mx:Label id="l1" text="HomeInsurance.swf"/> 
                <mx:ModuleLoader url="insurancemodules/HomeInsurance.swf"/> 
            </mx:VBox> 

            <mx:VBox id="vb2" label="The Preload Module"> 
                <mx:Label id="l2" text="LifeInsurance.swf"/> 
                <mx:ModuleLoader url="insurancemodules/LifeInsurance.swf"/> 
            </mx:VBox> 
        </mx:TabNavigator> 
    </mx:Panel> 
</mx:Application> 
4、ModuleEvent 
ModuleEvent->ProgressEvent->Event->Object 
ModuleEvent的五个常量如下: 
(1)PROGRESS 
当模块正在加载时触发,你可以访问模块的bytesLoaded和bytesTotal属性。 
(2)SETUP 
当有足够多的模块信息可用时触发。 
(3)READY 
当模块加载完成时触发。 
(4)UNLOAD 
当模块被卸载时触发。 
(5)ERROR 
当下载模块途中出现错误时触发。 
5、mx.core.IFlexModuleFactory: 
IFlexModuleFactory 接口提供引导 Flex 应用程序和动态加载的模块时应该使用的约定。调度complete事件之后,立即调用info()方法是合法的。当可安全调用create()方法时,功能良好的模块将调度ready事件。 
公共方法有两个: 
(1)public function create(... parameters):Object 
factory 方法,要求定义的实例是模块已知的。您可以提供可选参数集,以便构建工厂根据输入内容更改它们创建的内容。传递null指示,如果可能的话,创建默认的定义。 
(2)public function info():Object 
返回包含模块已知的静态数据的键/值对块。此方法始终成功,但是可以返回空对象。 
例如使用ModuleManager控制模块显示: 
<?xml version="1.0" encoding="utf-8"?> 
<!--FlexModule/ModuleManagerApp.mxml--> 
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" 
layout="vertical" creationComplete="creationHandler();"> 
<mx:Script> 
<![CDATA[ 
import mx.events.ModuleEvent; 
import mx.modules.ModuleManager; 
import mx.modules.IModuleInfo; 
private var _moduleInfo:IModuleInfo; 
private function creationHandler():void 

_moduleInfo = ModuleManager.getModule("insurancemodules/HomeInsurance.swf"); 
_moduleInfo.addEventListener( ModuleEvent.READY,moduleLoadHandler ); 
_moduleInfo.load(); 

private function moduleLoadHandler(evt:ModuleEvent):void 

canvas.addChild( _moduleInfo.factory.create() as DisplayObject ); 

]]> 
</mx:Script> 
<mx:Canvas id="canvas" width="500" height="500" /> 
</mx:Application> 
三、Module域 
通常将模块载入一个子域,那么模块里面的类定义都不是application域的。比如第一个模块载入了类PopUpManager,那么整合Application中,它就成了PopUpManager的拥有者,因为像这种manager都是单例的,如果另外一个模块稍后要使用这个PopUpManager,就会引发运行时异常。 
解决办法就是确保这些managers,比如PopUpManager和DragManager或者其他一些共享的服务是在application中定义的,这样就能确保所有模块都能够使用,代码如下: 
import mx.managers.PopUpManager; 
import mx.managers.DragManager; 
private var popUpManager:PopUpManager; 
private var dragManager:DragManager; 
这项技术同时也被应用到组件中,当module第一次使用组件时,将在它自己的域中拥有这些组件的类定义。如果别的module试图使用这些已经被另一个module使用的组件,它的定义将会不能匹配到现存的定义中。因此,为了避免组件的定义不匹配,在主应用程序中创建组件的实例,让所有的module去引用。 
但是这个坏处很明显,这些声明看起来莫名其妙,成为了一个个"木偶变量"。另一个解决方法是借助 ApplicationDomain 来共享这些代码和资源。在ModuleLoader 的creationComplete方法中加入moduleLoader.applicationDomain = ApplicationDomain.currentDomain; 表示将其加载到运行时库。对于使用ModuleManager,则可以在IModuleInfo的load方法里指定域。 
四、Module通信 
1、映射返回的引用对象 
模块访问Application通过其parentApplication属性来引用;Application访问模块则是把mx.modules.ModuleLoader的child属性返回的DisplayObject或mx.modules.IModuleInfo.factory.create方法返回的Object映射为模块类。比如var myModule = moduleLoader.child as MyModule;或var myModule:MyModule = _moduleInfo.factory.create() as MyModule;至于模块访问模块则可以通过parentApplication访问到Application再进行中转。 
为了让代码降低耦合,同时主应用程序能连接更多的类实例,最关键的是避免内存泄露和Module额外误编译导致文件体积增大等问题,我们需要使用接口来进行规范。比如var myModule = moduleLoader.child as IMyModule;或var myModule:MyModule = _moduleInfo.factory.create() as IMyModule; 
下面是一个映射接口的例子,我们假定创建多个供用户输入信息的表单模块。虽然它们具有不同的外观,或者对数据执行了不同的操作,但是访问模块数据的方法却是一样的。 
首先创建一个接口IUserEntry,列出用户信息相关的属性方法: 
//FlexModule/IuserEntry.as 
package 

import flash.events.IEventDispatcher; 

public interface IUserEntry extends IEventDispatcher 

function getFullName():String; 
function get firstName():String; 
function set firstName(str:String):void; 
function get lastName():String; 
function set lastName(str:String):void; 


然后创建实现此接口的Module: 
<?xml version="1.0" encoding="utf-8"?> 
<!--FlexModule/ContactEntry.mxml--> 
<mx:Module xmlns:mx="http://www.adobe.com/2006/mxml" 
implements="IUserEntry" 
layout="vertical" width="100%" height="100%"> 

<mx:Metadata> 
[Event (name="submit", type="flash.events.Event")] 
</mx:Metadata> 

<mx:Script> 
<![CDATA[ 
private var _firstName:String; 
private var _lastName:String; 
public static const SUBMIT:String = "submit"; 

private function submitHandler():void 

firstName = firstNameInput.text; 
lastName = lastNameInput.text; 
dispatchEvent(new Event( SUBMIT )); 


public function getFullName():String 

return _firstName + " "+ _lastName; 


[Bindable] 
public function get firstName():String 

return _firstName; 


public function set firstName( str:String ):void 

_firstName = str; 


[Bindable] 
public function get lastName():String 

return _lastName; 


public function set lastName( str:String ):void 

_lastName = str; 

]]> 
</mx:Script> 
<mx:Form> 
<mx:FormItem label="First Name:"> 
<mx:TextInput id="firstNameInput" width="100%" text="{firstName}"/> 
</mx:FormItem> 
<mx:FormItem label="Last Name:"> 
<mx:TextInput id="lastNameInput" width="100%" text="{lastName}"/> 
</mx:FormItem> 
<mx:Button label="submit" click="submitHandler();"/> 
</mx:Form> 
</mx:Module> 
最后使用<mx:ModuleLoader>的child属性(或mx.modules.IModuleInfo.factory.create方法)实例访问实现IUserEntry模块的数据: 
<?xml version="1.0" encoding="utf-8"?> 
<!--FlexModule/ModuleUseINterfaceApp.mxml--> 
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical"> 
<mx:Script> 
<![CDATA[ 
private var myModule:IUserEntry; 
private function moduleReadyHandler():void 

myModule = moduleLoader.child as IUserEntry; 
myModule.firstName="firstName from app"; 
myModule.lastName="lastName from app"; 
myModule.addEventListener( "submit", submitHandler ); 

private function submitHandler( evt:Event ):void 

welcomeField.text = 'Hello,'+myModule.getFullName(); 
trace( myModule.firstName + " "+ myModule.lastName ); 

]]> 
</mx:Script> 
<mx:ModuleLoader id="moduleLoader" url="ContactEntry.swf" 
ready="moduleReadyHandler();"/> 
<mx:Label id="welcomeField"/> 
</mx:Application> 
在这种通信方式中,我们只需要Module编译完成的swf文件和相应的接口说明即可。在主Application中,通过映射Module实现的接口得到不同Module对象的引用,然后调用get,set等接口中的方法即可完成通信。 
2、通过url给Module传参数数据 
在模块URL指定的SWF地址字符串后加上一些参数,当模块载入后即可使用其loaderInfo属性进行解析。 
比如在url后追加了查询字符串的模块: 
<?xml version="1.0" encoding="utf-8"?> 
<!--FlexModule/ModuleUseURLApp.mxml--> 
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" 
layout="vertical" creationComplete="creationHandler();"> 
<mx:Script> 
<![CDATA[ 
private static const F_NAME:String = "Ted"; 
private static const L_NAME:String = "Henderson"; 
private function creationHandler():void 

var params:String = "firstName="+ F_NAME +"&lastName="+ L_NAME; 
moduleLoader.url = "NameModule.swf?"+ params; 

]]> 
</mx:Script> 
<mx:ModuleLoader id="moduleLoader"/> 
</mx:Application> 
通过loaderInfo属性解析URL,获得传入的参数数据: 
<?xml version="1.0" encoding="utf-8"?> 
<!--FlexModule/NameModule.mxml--> 
<mx:Module xmlns:mx="http://www.adobe.com/2006/mxml" 
width="400" height="300" layout="absolute" 
creationComplete="creationHandler();"> 
<mx:Script> 
<![CDATA[ 
import mx.utils.ObjectProxy; 

[Bindable] 
private var _proxy:ObjectProxy; 

private function creationHandler():void 

_proxy = new ObjectProxy(); 
var pattern:RegExp = /.*\?/; 
var query:String = loaderInfo.url.toString(); 
query = query.replace( pattern, ""); 
var params:Array = query.split( "&"); 
for( var i:int = 0; i < params.length; i++ ) 

var keyVal:Array = ( params[i]).toString().split("="); 
_proxy[keyVal[0]] = keyVal[1]; 


]]> 
</mx:Script> 
<mx:Text text="{'Hello,'+ _proxy.firstName + ' '+_proxy.lastName}" /> 
</mx:Module> 
这种通信方式的具体思路是,在Module中拼接要跳转的其他Module地址和参数值,比如var url:String="eqm/updateSmall.swf?eqmID="+this.DG.selectedItem.eqmID as String; 
this.parentApplication.jumpTo(url); 
然后通过主Application进行中转。 
public function jumpTo(toUrl:String):void 

    moduleLoader.url=toUrl; 
    moduleLoader.loadModule(); 

也可以不使用parentApplication这种不太合规范的属性,改为在Module中抛出携带参数的事件,在主Application中监听此事件,获取事件携带的参数值后传入将要跳转的另一个Module中。具体代码可参考通信方式1中的myModule.addEventListener( "submit", submitHandler ); 
也可以在主Application中抛出事件,在Module中进行监听,具体代码参见附件FlexModule中的GreenAndRedModuleApp.mxml(额外使用了DynamicEvent,参考网址:http://yakovfain.javadevelopersjournal.com/flex_best_practices_sketch_1_an_application_with_a_single_.htm)
五、使用连接报告优化Module 
默认情况下,编译器会将模块所依赖的所有自定义组件和框架代码都编译进SWF文件中。这其中有很多代码是主程序和其它模块所共用的。我们可以使用link-report命令行参数生成一个连接报告文件来列出主程序依赖的类,然后在编译模块时再使用link-externs连接报告文件。 
>mxmlc -link-report=report.xml MyApplication.mxml 
>mxmlc -link-externs=report.xml MyModule.mxml 
很显然,这样将会导致Module与目标Application产生“绑定”,即这个Module无法再被其他Application所使用(可以绑定到一个空的Application以实现多应用),因此在新建Module时需要注意其Optimize for application选项的设置。另外,右键项目选择Properties->Flex Modules也可进一步修改。 

 


注意事项: 
   1 Module要想最小,一定要把其他依赖的Lib库设置成运行时共享库 
   2 编译主应用程序的时候,设置编译选项-keep-all-type-selectors=true,否则加载出来的模块,里面的部分组件会丢失样式,甚至报空指针错误 

参考网址:http://www.iteye.com/topic/461032 

 

分享到:
评论

相关推荐

    Flex与ActionScript3程序开发

    目录: ... 第16章 专题知识 第4篇 性能优化篇 第17章 Module机制 第18章 RSL运行时共享库 第5篇 Flex通信篇 第19章 与JavaScript/AJAX通信 第20章 Flex与PHP通信 第21章 Flex与Java EE通信

    专题资料(2021-2022年)Hp刀片服务器VirtualConnect特性介绍.doc

    例如,HP VC Flex Fabric 10Gb/24-Port Module是一款混合模块,支持Enet和FC。 2. **Ethernet**:这一系列的Virtual Connect专注于以太网虚拟化,如HP 1/10Gb VC-Enet Module,提供1Gbps到10Gbps的连接速度,用于...

    能源领域:基于MATLAB的阶梯式碳交易与供需灵活双响应综合能源系统优化调度

    内容概要:本文详细介绍了考虑阶梯式碳交易与供需灵活双响应的综合能源系统优化调度方法。在供给侧,引入了有机朗肯循环(ORC)实现热电联产机组的灵活响应;在需求侧,提出电、热、气负荷之间的可替代性,以提高能源利用效率。构建了以最小化碳排放成本、购能成本、弃风成本和需求响应成本为目标的优化调度模型,并采用MATLAB和CPLEX进行了模型构建和求解。文中提供了具体的代码示例,展示了如何处理热电耦合、负荷替代和阶梯式碳交易等问题。 适合人群:从事能源系统优化、电力系统调度、碳交易等相关领域的研究人员和技术人员。 使用场景及目标:适用于需要优化能源系统调度、降低成本并减少碳排放的实际应用场景。目标是帮助读者理解和掌握如何通过先进的技术和算法实现更加灵活和高效的能源调度。 其他说明:文章提供了完整的代码实现和服务支持,包括12种典型场景的数据集和预设模型,方便读者快速上手实践。

    工业自动化中欧姆龙CP1H与东元N310变频器基于Modbus RTU通讯的实战程序

    内容概要:本文详细介绍了一个利用欧姆龙CP1H PLC及其CIF11通讯板与三台东元N310变频器进行通讯的实战案例。主要内容涵盖硬件配置(包括接线方式和终端电阻设置)、变频器参数设置(如波特率、站号等)、PLC编程(含频率设定、实际频率和输出电压读取的具体指令及其实现方法)、以及调试过程中遇到的问题和解决方案。此外,还提供了关于如何扩展更多变频器的方法,强调了通讯稳定性和高效性的优化措施。 适合人群:从事工业自动化领域的工程师和技术人员,尤其是那些需要掌握PLC与变频器通讯技能的人群。 使用场景及目标:适用于需要对多个变频器进行集中控制和监测的应用场合,如工厂生产线、电力系统等。主要目的是提高系统的集成度和可靠性,降低维护成本。 其他说明:文中不仅给出了详细的代码片段,还包括了许多宝贵的实践经验,对于初学者来说是非常好的参考资料。同时,作者也提到了一些常见的陷阱和注意事项,有助于读者少走弯路。

    基于Simulink的TCR+FC型SVC无功补偿仿真模型构建与优化

    内容概要:本文详细介绍了如何在Simulink中构建TCR+FC型静止无功补偿器(SVC)的仿真模型。首先,文章解释了TCR(晶闸管控制电抗器)和FC(固定电容器)的工作原理及其在电力系统中的重要性。接着,逐步讲解了模型搭建的关键步骤,包括晶闸管参数设置、触发脉冲生成、滤波器设计以及控制策略的选择。文中特别强调了触发角控制对补偿效果的影响,并提供了具体的MATLAB代码示例。此外,作者分享了许多实践经验,如如何应对现场环境变化带来的参数偏差、如何防止谐振等问题。最后,通过对不同工况下仿真结果的分析,展示了该模型在改善电压稳定性、提高功率因数方面的显著效果。 适合人群:从事电力系统研究和技术开发的专业人士,尤其是那些希望深入了解SVC工作原理及其仿真方法的研究人员和工程师。 使用场景及目标:适用于需要进行电力系统无功补偿装置性能评估、优化设计的研究机构或企业。主要目标是在确保系统稳定性的前提下,最大化提升无功补偿效率,降低谐波污染,从而保障电网的安全运行。 其他说明:文中不仅提供了详细的建模指导,还包括许多实用的小贴士和注意事项,帮助读者避开常见陷阱,快速掌握核心技术要点。同时,附带的实际案例分析有助于加深理解,使读者能够将所学应用于实际工程项目中。

    spring-ai-chroma-store-1.0.0-M6.jar中文文档.zip

    # 压缩文件中包含: 中文文档 jar包下载地址 Maven依赖 Gradle依赖 源代码下载地址 # 本文件关键字: jar中文文档.zip,java,jar包,Maven,第三方jar包,组件,开源组件,第三方组件,Gradle,中文API文档,手册,开发手册,使用手册,参考手册 # 使用方法: 解压最外层zip,再解压其中的zip包,双击 【index.html】 文件,即可用浏览器打开、进行查看。 # 特殊说明: ·本文档为人性化翻译,精心制作,请放心使用。 ·只翻译了该翻译的内容,如:注释、说明、描述、用法讲解 等; ·不该翻译的内容保持原样,如:类名、方法名、包名、类型、关键字、代码 等。 # 温馨提示: (1)为了防止解压后路径太长导致浏览器无法打开,推荐在解压时选择“解压到当前文件夹”(放心,自带文件夹,文件不会散落一地); (2)有时,一套Java组件会有多个jar,所以在下载前,请仔细阅读本篇描述,以确保这就是你需要的文件;

    智云物业小程序v3.5.0高级版+微信+支付宝前端.zip

    智云物业小程序v3.5.0高级版 微信 支付宝前端 版本号:3.5.0智云物业 抄表可以直接录入表号 社区发图多由5张改为9张 添加付出通道对接 车位锁bug批改 细节调整和优化 功能特色: 1. 可视化楼宇房产管理,一键生成楼宇房产(支持EXCEL导入) 2. 住户管理(业主、成员、租户),严格、宽松和自由三种注册方式 3. 报修和投诉建议完整处理流程(派单与抢单),内部工单处理(派单与抢单) 4. 智能门禁(微信开门、定位防骚扰、开门日志)、人脸识别、蓝牙 5. 商铺和车位管理,一键生成或EXCEL导入 6. 多收费项目管理,批量生成账单,前后台收银,可视化管理 7. 社区论坛、邻里互动、新动态 8. WQ独立后台、物业独立后台,权限角色完全分开 9. 版权自定义设置、页面自定义图标及链接 10. 统计分析报表、打通WQ会员、会员组及积分 11. 物业手机端住户管理、上门收费、账单核销、抄表录入、巡更 12. 线下周边商家(集积分、支付、活动、红包于一体) 13. 积分红包、挪车服务、打包小程序、智能充电站、自助智能设备(如:洗车机、饮水机等) 14. 全局权限控制、公众号授权、自定义系统帮助 15. 对接多家车牌识别管理系统,在线缴费、办理月卡、统计报表 16.?快递驿站、活动管理(投票、报名、问卷)、管理看板

    西门子S7-1200 PLC在新能源物料输送系统中的RS485通讯与称重仪表集成应用

    内容概要:本文详细介绍了在一个新能源物料输送系统中,利用西门子S7-1200 PLC和昆仑通态触摸屏实现物料输送控制的具体方法。主要内容涵盖硬件配置(如PLC、称重仪表、RS485通信模块)、通信配置(如RS485参数设置)、软件开发(如博途V16编程、模拟量采集、物料输送控制逻辑)以及触摸屏组态开发等方面。文中不仅提供了具体的配置步骤和技术细节,还分享了许多实际开发中的经验和常见问题解决方法。 适合人群:自动化领域的工程师和技术人员,尤其是那些正在从事或计划从事PLC控制系统的开发和维护工作的人员。 使用场景及目标:适用于需要开发类似物料输送系统的工程项目,旨在帮助读者掌握PLC控制系统的开发技能,提高系统稳定性和可靠性,减少开发过程中的错误和问题。 其他说明:文中提到的实际案例和开发经验对于理解和解决工业自动化项目中的常见问题非常有帮助。同时,文中提供的代码片段和配置示例可以直接应用于实际项目中,方便读者快速上手。

    光伏储能与虚拟同步发电机并网的Matlab/Simulink建模及优化

    内容概要:本文详细介绍了如何在Matlab/Simulink环境下构建光伏储能系统与虚拟同步发电机(VSG)并网的模型。首先,文章阐述了整体思路,即实现直流侧光储与VSG并网的完美配合。接着,分别讲解了光伏部分、储能部分和VSG部分的具体实现方法,包括光伏电池模型的选择、储能电池的参数设置以及VSG控制算法的设计。此外,文章还讨论了光照强度变化的设置及其对系统的影响,并提供了详细的波形分析。最后,针对模型调试过程中遇到的问题提出了有效的解决方案。 适合人群:从事电力电子、新能源发电领域的研究人员和技术人员,尤其是熟悉Matlab/Simulink工具的用户。 使用场景及目标:适用于希望深入了解光伏储能系统与虚拟同步发电机并网机制的研究人员和技术人员。主要目标是掌握如何在Matlab/Simulink中搭建和优化此类模型,以便更好地应用于实际工程实践中。 其他说明:文中提供的代码片段和调试技巧对于初学者非常有帮助,同时也为高级用户提供了一些优化建议。通过对不同参数的调整,如虚拟惯量、阻尼系数等,可以进一步提高系统的稳定性和响应速度。

    【蓝桥杯EDA】客观题解析:第十二届省赛第二场真题.pdf

    【蓝桥杯EDA】客观题解析

    J1939信号详解及SPN查询表

    表格可以详细查询到商用车CAN通信里每个信号具体的定义,SPN,每一位信号的定义

    直驱永磁风机Simulink仿真模型:内外双环控制、低电压穿越及MPPT研究

    内容概要:本文详细介绍了直驱永磁风机的Simulink仿真模型,涵盖了机侧和网侧控制、低电压穿越控制(chopper电路控制)、风速模拟及最大功率点跟踪(MPPT)。机侧控制采用了内外双环结构,通过零d轴电流(ZDC)控制降低铜损,提高效率;MPPT则通过最优转矩(OTC)控制实现。网侧控制包括并网和脱网两种模式,分别采用双闭环解耦控制和闭环无源逆变控制。低电压穿越控制通过chopper电路确保电网电压异常时风机的稳定运行。风速模拟部分使用了复杂的风速模型,使仿真更加接近实际情况。此外,文中还提到了详细的参数设定和调试经验,以及相关文献的支持。 适合人群:从事风电系统设计、仿真建模的研究人员和技术人员,尤其是对直驱永磁风机及其控制系统感兴趣的工程师。 使用场景及目标:适用于需要深入了解直驱永磁风机Simulink仿真的研究人员和技术人员。主要目标是掌握直驱永磁风机的控制策略,包括内外双环控制、低电压穿越控制、风速模拟及MPPT的具体实现方法,以便应用于实际项目中。 其他说明:文中提供的代码片段和参数设定有助于读者更好地理解和应用这些控制策略。同时,参考文献也为进一步研究提供了理论依据。

    基于Simulink的永磁同步电机多故障诊断与处理策略

    内容概要:本文详细介绍了如何在Simulink环境中构建永磁同步电机(PMSM)的多故障诊断模型,特别是针对绕组匝间短路和转子偏心故障的联合诊断。文章首先展示了如何通过MATLAB代码实现绕组电阻变化模型,解释了故障注入的关键参数设置及其背后的物理意义。接着讨论了混合故障建模的方法,强调了机械偏心和电气短路之间的耦合关系,并提供了具体的Simulink模块连接方式。文中还探讨了多种先进的故障特征提取技术,如改进的S变换、小波包分解以及经验模态分解,并推荐使用MATLAB的signalDiagnosticDesigner工具来自动生成特征提取代码。此外,文章介绍了不同类型的观测器设计,包括磁链观测器和滑模观测器,并分享了一些实用的经验技巧。最后,文章提出了几种有效的故障分类算法,如改进的KNN和支持向量机结合长短期记忆网络的混合模型。 适合人群:从事电机控制系统设计的研究人员和技术工程师,尤其是那些对永磁同步电机故障诊断感兴趣的从业者。 使用场景及目标:适用于希望深入了解永磁同步电机内部故障机制并在Simulink平台上进行仿真的专业人士。主要目标是提高故障检测精度,优化故障处理策略,确保系统的稳定性和可靠性。 其他说明:文中提供的代码片段和建模思路可以帮助读者快速入门并掌握复杂的故障诊断流程。同时,作者还分享了许多宝贵的实践经验,有助于避免常见的错误和陷阱。

    三菱Q系列11轴运动控制系统:PLC程序、触摸屏程序及电气设计详解

    内容概要:本文详细介绍了三菱Q系列11轴运动控制项目的实施细节,涵盖PLC程序、触摸屏程序、电气清单及完整电路图。PLC程序采用分工位编辑,确保各工位独立控制,便于调试和维护。触摸屏程序实现了对各工位的实时监控和参数修改,增强了系统的灵活性。电气清单详尽列出所有电气元件及其规格,电路图展示了元件间的连接关系,有助于现场布局和故障排查。此外,文中还涉及定位模块和模拟量模块的应用,提升了系统的控制精度和稳定性。 适合人群:从事工业自动化领域的工程师和技术人员,尤其是那些负责多轴运动控制系统的开发和维护人员。 使用场景及目标:适用于需要进行复杂多轴运动控制的工业生产线,旨在提高生产效率、降低维护成本,并提供详细的编程和设计指导。 其他说明:文章不仅提供了具体的代码示例和电路图,还包括了许多实用的设计技巧和注意事项,如异常处理机制、信号隔离方法以及变量命名规范等,这些都是实际项目中非常宝贵的经验总结。

    晫璨智慧环卫建设解决方案PPT(32页).pptx

    在当今智慧城市的建设浪潮中,智慧环卫作为城市管理的重要组成部分,正以其独特的魅力引领着环卫行业的变革。本方案旨在通过一系列高科技手段,如物联网、大数据、云计算等,全面提升环卫作业效率与管理水平,为城市居民创造更加清洁、宜居的生活环境。 一、智慧环卫系统概述与核心亮点 智慧环卫系统是一个集机械化保洁、垃圾清运、设施管理、事件指挥调度等多功能于一体的综合性管理平台。其核心亮点在于通过高精度定位、实时监控与智能分析,实现环卫作业的精细化管理。例如,机械化保洁管理子系统能够实时监控机扫车、洒水车等作业车辆的运行状态,自动规划最优作业路线,并根据作业完成情况生成考核评价报表,极大地提高了作业效率与服务质量。同时,垃圾清运管理子系统则通过安装GPS定位设备和油量传感器,对清运车辆进行全方位监控,确保垃圾清运过程的规范与高效,有效解决了城市垃圾堆积与随意倾倒的问题。此外,系统还配备了垃圾箱满溢报警系统,通过智能感应技术,当垃圾箱内垃圾达到预设高度时自动报警,提醒作业人员及时清运,避免了因垃圾满溢而引发的居民投诉与环境污染。 二、智慧环卫系统的趣味性与知识性融合 智慧环卫系统不仅实用性强,还蕴含着丰富的趣味性与知识性。以餐厨垃圾收运管理子系统为例,该系统通过为餐厨垃圾收运车辆安装GPS定位、车载称重、视频监控等多种感知设备,实现了对餐厨垃圾收运过程的全程监控与智能管理。作业人员可以通过手机APP实时查看车辆位置、行驶轨迹及收运情况,仿佛在玩一场现实版的“垃圾追踪游戏”。同时,系统还能自动生成餐厨垃圾收运统计报表,帮助管理人员轻松掌握收运量、违规情况等关键数据,让数据管理变得既科学又有趣。此外,中转站视频监控子系统更是将趣味性与实用性完美结合,通过高清摄像头与双向语音对讲功能,实现了对中转站内外环境的实时监控与远程指挥,让管理人员足不出户就能掌控全局,仿佛拥有了一双“千里眼”和一对“顺风耳”。 三、智慧环卫系统的未来展望与社会价值 随着科技的不断进步与智慧城市建设的深入推进,智慧环卫系统将迎来更加广阔的发展前景。未来,智慧环卫系统将更加注重数据的深度挖掘与分析,通过大数据与人工智能技术,为城市环卫管理提供更加精准、高效的决策支持。同时,系统还将加强与其他城市管理系统的互联互通,实现资源共享与协同作战,共同推动城市管理的智能化、精细化水平。从社会价值来看,智慧环卫系统的推广与应用将有效提升城市环境卫生质量,改善居民生活环境,提升城市形象与竞争力。此外,系统还能通过优化作业流程、减少资源浪费等方式,为城市可持续发展贡献重要力量。可以说,智慧环卫系统不仅是城市管理的得力助手,更是推动社会进步与文明发展的重要力量。

    MATLAB车牌识别技术详解:从图像预处理到字符识别的全流程解析

    内容概要:本文详细介绍了基于MATLAB的车牌识别技术,涵盖了从图像预处理到最终字符识别的完整流程。首先,文章强调了MATLAB环境配置及相关图像处理工具箱的重要性。接着,逐步展示了核心代码片段,如图像读取、灰度转换、边缘检测、形态学操作、轮廓提取、车牌区域筛选等关键技术。此外,还探讨了字符分割方法,包括垂直投影法和连通域分析,并介绍了模板匹配用于字符识别的具体实现。文中不仅提供了代码示例,还附带了详细的Word版解析,解释了各个函数的作用及参数选择依据,帮助读者深入理解每一环节的工作机制。 适合人群:对图像处理和车牌识别感兴趣的初学者、有一定编程基础的研究人员和技术爱好者。 使用场景及目标:适用于学术研究、教学演示以及小型项目的快速原型开发。主要目标是使读者能够掌握车牌识别的基本原理和技术细节,从而应用于实际场景中。 其他说明:文章特别指出了一些常见问题及其解决办法,例如如何应对复杂光照条件、字符粘连等问题,并给出了具体的优化建议。同时,强调了代码实现过程中需要注意的各种细节,如参数调整、图像预处理等,以提高识别精度。

    【模型预测控制MPC】使用离散、连续、线性或非线性模型对预测控制进行建模附Matlab代码.rar

    1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。

    误码率二进制相移键控 BER 8PSK附Matlab代码.rar

    1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。

    一种利用并网变流器获得最大允许电网支持的分析方法[MAS技术 变流器电网支座分析优化]附Matlab代码.rar

    1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。

Global site tag (gtag.js) - Google Analytics