从一个swf按模块分解成多个swf,而分解成为不同的swf势必就会用到Flex中的Module,本文将根据个人经验阐述在运用
Module模块化编程时需要注意的事项以及相关解决方案;
Environment: Flash Builder;Flex SDK4.1;IE7;1.创建module时注意Module SWF size 的参数设置;
如图我们创建Module1:
注意图中两个红色箭头,我们平常都会忽视这个选项,至少我最开始是忽视了;如果选"Optimize for application",意味着该Module1只能被TestMainModuel加载,其他的application
将无法加载Module1,生成的swf size 相对会小些;而如果选"Do not optimize",其他的applicaton也可以加载该swf,而swf size 会相对大些;
2.在module中使用PopUpManager popUp displayObject (以当前窗口为父容器)会报"PopUpManagerImpl中无法访问控对象引用或属性的错误":
错误截图:
解决方案:只需要在Application中导入PopUpManager并显示声明下,即添加如下code:
import mx.managers.PopUpManager;
private var pum:PopUpManager;
不信你you can try it,但是注意:一定要在的在Module中popup.
测试代码:
//在module中弹出窗口以当前窗口为父容器
private function popupWinBaseOnThis():void {
var t:TitleWindow = new TitleWindow();
PopUpManager.addPopUp(t,this as DisplayObject,true);
}
3.在module中使用PopUpManager popUp displayObject (以主应用程序(根容器)为父容器)会报"Undefined stat 'inactive'"错误:
错误截图:
测试代码:
//在module中弹出窗口以主应用程序(根容器)为父容器
private function popUpWinBaseOnApp():void {
var tw:TitleWindow = new TitleWindow();
PopUpManager.addPopUp(tw,FlexGlobals.topLevelApplication as DisplayObject,true);
}
解决方案:
(1). 在Application中导入PopUpManager并显示声明下,即添加如下code:
import mx.managers.PopUpManager;
private var pum:PopUpManager;
(2). 在popupwindow加上moduleFactory参数(该参数从Module中取得), code如下:
PopUpManager.createPopUp(FlexGlobals.topLevelApplication as DisplayObject,TitleWindow,false,null,Model1.moduleFactory));
ps:问题3,还可能出现的现象是"Error: Can not find the appearance of"或者弹出框里边的内容格式排版或者样式发生异常,只需要在后边加上一个moduleFactory的参数即可
4. module应用中容器中添加子控件,子控件再添加子控件时,顺序要注意:先将子控件添加到主容器中,再在子控件中添加child.否则回报skin找不到错误
这里贴出我项目中用到例子:
private function getHGView(isMax:Boolean=false,str:String=""):HGroup {
var hg1:HGroup = new HGroup();
this.addElement(hg1);
var lb1:Label = new Label();
if(isMax){
lb1.text = "最大值:";
maxInput = new DateInput();
maxInput.dateStr = str;
hg1.addElement(lb1);
hg1.addElement(maxInput);
}else{
lb1.text = "最小值:";
minInput = new DateInput();
minInput.dateStr = str;
hg1.addElement(lb1);
hg1.addElement(minInput);
}
return hg1;
}
我本来想重现这个现象,unfortunately,经过一丝的努力后,我仍然没能让她重现,因此这一小点我觉得说服了还不够,仅供参考吧,倘若某天哥们你遇到类似问题时,不妨试试我这个写法。
如果有兴趣的话,我们一起来探究下发生这一系列情况的原因是什么吧?(跟帖讨论)
Application:
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
minWidth="955" minHeight="600">
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<fx:Script>
<![CDATA[
import mx.managers.PopUpManager;
private var pum:PopUpManager;
//optimized for application
private function loadSwf():void {
moduleLoad.unloadModule();
moduleLoad.url = "module/Module1.swf";
moduleLoad.loadModule();
}
//do not optimize
private function loadSwf2():void {
moduleLoad.unloadModule();
moduleLoad.url = "module/SingleAppModule.swf";
moduleLoad.loadModule();
}
]]>
</fx:Script>
<s:layout>
<s:VerticalLayout verticalAlign="middle"/>
</s:layout>
<s:HGroup>
<s:Button label="load 1 swf" click="loadSwf()" width="100" height="100"/>
<s:Button label="load two swf" click="loadSwf2()" width="100" height="100"/>
</s:HGroup>
<mx:ModuleLoader id="moduleLoad" width="500" height="500" />
</s:Application>
Module:
<?xml version="1.0" encoding="utf-8"?>
<mx:Module xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" layout="vertical" width="400" height="300">
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<fx:Script>
<![CDATA[
import mx.core.FlexGlobals;
import mx.managers.PopUpManager;
import spark.components.Label;
import spark.components.TitleWindow;
import spark.components.VGroup;
//在module中弹出窗口以当前窗口为父容器
private function popupWinBaseOnThis():void {
var t:TitleWindow = new TitleWindow();
PopUpManager.addPopUp(t,this as DisplayObject,true);
}
//在module中弹出窗口以主应用程序(根容器)为父容器
private function popUpWinBaseOnApp():void {
//var tw:TitleWindow = new TitleWindow();
//PopUpManager.addPopUp(tw,FlexGlobals.topLevelApplication as DisplayObject,true);
//解决方案
var tw:TitleWindow = TitleWindow(PopUpManager.createPopUp(FlexGlobals.topLevelApplication as DisplayObject,TitleWindow,false,null,this.moduleFactory));
}
]]>
</fx:Script>
<s:HGroup>
<s:CheckBox label="Module1"/>
<s:Button label="Module1"/>
<s:Button label="pop up" click="popupWinBaseOnThis()" width="50" height="50"/>
<s:Button label="pop up by Util" click="popUpWinBaseOnApp()" width="50" height="50"/>
</s:HGroup>
</mx:Module>