import mx.events.ModuleEvent;
import mx.modules.*;
import mx.controls.Alert;
private function errorHandler(e:ModuleEvent):void {
Alert.show("There was an error loading the module." +
" Please contact the Help Desk.");
trace(e.errorText);
}
public function createModule():void {
if (chartModuleLoader.url == ti1.text) {
// If they are the same,call loadModule.
chartModuleLoader.loadModule();
} else {
// If they are not the same,then change the url,
// which triggers a call to the loadModule() method.
chartModuleLoader.url = ti1.text;
}
}
public function removeModule():void {
chartModuleLoader.unloadModule();
}
="Module Example"="90%"="10"="URL:"="200"="ti1"="ColumnChartModule.swf"/
="createModule()"="removeModule()"="chartModuleLoader" error="errorHandler(event)" 应用progress事件?
使用ModuleLoader的progress事件可以让你跟踪模块实例加载的进度信息。参考示例
<!--
modules/SimpleProgressEventHandler.mxml -->
import mx.events.ModuleEvent;
import flash.events.ProgressEvent;
import mx.modules.*;
[Bindable]
public var progBar:String = "";
[Bindable]
public var progMessage:String = "";
private function progressEventHandler(e:ProgressEvent):void {
progBar += ".";
progMessage =
"Module " +
Math.round((e.bytesLoaded/e.bytesTotal) * 100) +
"% loaded";
}
public function createModule():void {
chartModuleLoader.loadModule();
}
public function removeModule():void {
chartModuleLoader.unloadModule();
progBar = "";
progMessage = "";
}
="{progMessage}"="{progBar}"mx:ModuleLoader
progress="progressEventHandler(event)" 怎样共享和传输Module模块间数据?
Module模块是一个容器,每个独立的模块对象都相当于一个自定义组件。有以下几种方式可以实现模块-模块、模块-主应用、主应用-模块、模块-一般自定义组件间的数据传输和通信。?
利用ModuleLoader的child、ModuleManager的factory、以及Application的parentApplication属性存取Module模块和主应用文件对象索引。?
因为Module模块在ModuleLoader中通常用url属性来指定,所以我们可以通过在url上面拼GET参数,然后在Module模块中解析这些拼上去的参数的方式来传输数据。?
通过ActionScript接口方式。你可以定义一个ActionScript接口,这个接口定义了一系列方法和属性。Module模块和主应用Application都可以访问这些属性。从而实现数据共享。?
?在主应用Application中访问Module模块对象?
我们可以在主应用Application中访问子Module模块对象中定义的方法和属性。下面示例展示了通过ModuleLoader的child属性拿到子Module模块对象索引,然后调用其定义的公共方法getTitle().?
modules/ParentApplication.mxml
>
[Bindable]
private var s:String;
private function getTitle():void {
s = (m1.child as ChildModule1).getModTitle();
}
]]>="{s}"="ChildModule1.swf"="m1" ready="getTitle()"
modules/ChildModule1.mxml
// Defines the method that the application calls.
public function getModTitle():String {
return "Child Module 1";
}
通过这种方式得到子Module模块的索引导致了主应用Application和Module模块之间的紧耦合,不利于模块逻辑的重用。同样地,利用ModuleManager的factory属性也可以拿到当前ModuleLoader的子模块对象的索引。参考以下示例,模块文件为,
modules/mxmlmodules/SimpleModule.mxml
public function computeAnswer(a:Number,b:Number):Number {
return a + b;
}
主应用Application为
modules/mxmlmodules/SimpleMXMLApp.mxml
="initApp()"
import mx.modules.IModuleInfo;
import mx.modules.ModuleManager;
public var assetModule:IModuleInfo;
public var sm:Object;
[Bindable]
public var answer:Number = 0;
public function initApp():void {
// Get the IModuleInfo interface for the specified URL.
assetModule = ModuleManager.getModule("SimpleModule.swf");
assetModule.addEventListener("ready",getModuleInstance);
assetModule.load();
}
public function getModuleInstance(e:Event):void {
// Get an instance of the module.
sm = assetModule.factory.create() as SimpleModule;
}
public function addNumbers():void {
var a:Number = Number(ti1.text);
var b:Number = Number(ti2.text);
// Call a method on the module.
answer = sm.computeAnswer(a,b).toString();
}
mx:FormHeading ="Enter values to sum."="First Number"="50"="Second Number"="ti2"="Result"="ti3"="100"="{answer}"="b1"="Compute"="addNumbers()" 在Module模块对象中存取主应用Application?
Module模块可以通过其parentApplication属性拿到主应用Application对象的索引,通过这个索引可以访问主应用对象的公共方法和属性。参考以下示例,Module模块文件为
modules/ChartChildModule.mxml
="getDataFromParent()"
import mx.collections.ArrayCollection;
[Bindable]
private var expenses:ArrayCollection;
// Access properties of the parent application.
private function getDataFromParent():void {
expenses = parentApplication.expenses;
}
mx:ColumnChart ="myChart" dataProvider="{expenses}"mx:horizontalAxismx:CategoryAxis
dataProvider="{expenses}"
categoryField="Month"mx:seriesmx:ColumnSeries
xField
yField="Profit"
displayName="Expenses"mx:ColumnChartmx:Legend ="{myChart}"="expenses = parentApplication.getNewData();"="Get New Data" 主应用文件为
modules/ChartChildModuleLoader.mxml
import mx.collections.ArrayCollection;
[Bindable]
public var expenses:ArrayCollection = new ArrayCollection([
{Month:"Jan",Profit:2000,Expenses:1500},
{Month:"Feb",Profit:1000,Expenses:200},
{Month:"Mar",Profit:1500,Expenses:500}
]);
public function getNewData():ArrayCollection {
return new ArrayCollection([
{Month:"Apr",Expenses:1100},
{Month:"May",Profit:1300,Expenses:500},
{Month:"Jun",Profit:1200,Expenses:600}
]);
}
="ChartChildModule.swf"="m1" 不过这种方式导致的一个缺点是,自定义的Module模块文件的可移植特性将大打折扣。?
在一个Module模块对象中存取另一个Module模块对象?
同样地,我们也可以利用ModuleLoader的child属性,在一个Module模块对象中拿到另一个Module模块对象的索引,通过这个索引访问当前Module模块对象的公共方法和属性。参考以下示例,主应用文件
modules/TitleModuleLoader.mxml
="InterModule1.swf"="InterModule2.swf"="m2" Module1文件
modules/InterModule1.mxml
// Defines the method that the other module calls.
public function getNewTitle():String {
return "New Module Title";
}
Module2文件
modules/InterModule2.mxml
[Bindable]
private var title:String;
// Call method of another module.
private function changeTitle():void {
title = parentApplication.m1.child.getNewTitle();
}
="Title: "="myTitle"="{title}"="Change Title"="changeTitle()" 通过拼ModuleLoader的url参数方式实现数据传输?
在url上面拼GET参数基本上是这种格式,url=module1.swf?param1=value1¶m2=value2?
比如在主应用文件Application中拼一系列GET参数到ModuleLoader的url属性上,在Module模块文件中解析并处理这些参数,参考以下示例,主应用文件
modules/QueryStringApp.mxml
="500"="400"
public function initModule():void {
// Build query string so that it looks something like this:
// "QueryStringModule.swf?firstName=Nick&lastName=Danger"
var s:String = "QueryStringModule.swf?" + "firstName=" +
ti1.text + "&lastName=" + ti2.text;
// Changing the url property of the ModuleLoader causes
// the ModuleLoader to load a new module.
m1.url = s;
}
="fi1"="First Name:"="ti1"="fi2"="Last Name:"="ti2"="Submit"="initModule()" 模块文件
modules/QueryStringModule.mxml
="parseString()"
import mx.utils.*;
[Bindable]
private var salutation:String;
public var o:Object = {};
public function parseString():void {
try {
// Remove everything before the question mark,including
// the question mark.
var myPattern:RegExp = /.*?/;
var s:String = this.loaderInfo.url.toString();
s = s.replace(myPattern,"");
// Create an Array of name=value Strings.
var params:Array = s.split("&");
// Print the params that are in the Array.
var keyStr:String;
var valueStr:String;
var paramObj:Object = params;
for (keyStr in paramObj) {
valueStr = String(paramObj[keyStr]);
ta1.text += keyStr + ":" + valueStr + "n";
}
// Set the values of the salutation.
for (var i:int = 0; i < params.length; i++) {
var tempA:Array = params[i].split("=");
if (tempA[0] == "firstName") {
o.firstName = tempA[1];
}
if (tempA[0] == "lastName") {
o.lastName = tempA[1];
}
}
if (StringUtil.trim(o.firstName) != "" &&
StringUtil.trim(o.lastName) != "") {
salutation = "Welcome " +
o.firstName + " " + o.lastName + "!";
} else {
salutation = "Full name not entered."
}
} catch (e:Error) {
trace(e);
}
// Show some of the information available through loaderInfo:
trace("AS version: " + this.loaderInfo.actionScriptVersion);
trace("App height: " + this.loaderInfo.height);
trace("App width: " + this.loaderInfo.width);
trace("App bytes: " + this.loaderInfo.bytesTotal);
}
="{salutation}"mx:TextArea height="ta1" 利用ActionScript接口实现Module模块间的数据通信?
在面向对象的编程中,我们讲要面向接口编程。面向接口的编程方式从一定程度上解决了相互关联的模块间的紧密耦合问题。以上提到的所有数据传输和共享方式都在不同程度上导致了模块间的紧耦合。不过,Flex提供了一种利用标准的ActionScript接口实现Module模块间数据通信的方式。具体地说,对于Module模块对象和主应用Application对象间的通信,我们可以定义一个ActionScript接口,Module模块对象实现了这个接口中定义的方法和属性,那么主应用Application就可以访问这个接口中定义的属性和方法。接口中定义了Module模块对象和主应用Application需要共享的数据和方法,是两者间共同的一个契约,同时也实现了接口和实现的分离,达到了松耦合的目的。参考以下示例,主应用Application
modules/interfaceexample/Main.mxml
import mx.events.ModuleEvent;
import mx.modules.ModuleManager;
[Bindable]
public var selectedItem:Object;
[Bindable]
public var currentModuleName:String;
private function applyModuleSettings(e:Event):void {
// Cast the ModuleLoader's child to the interface.
// This child is an instance of the module.
// You can now call methods on that instance.
var ichild:* = mod.child as IModuleInterface;
if (mod.child != null) {
// Call setters in the module to adjust its
// appearance when it loads.
ichild.setAdjusterID(myId.text);
ichild.setBackgroundColor(myColor.selectedColor);
} else {
trace("Uh oh. The mod.child property is null");
}
// Set the value of a local variable by calling a method
// on the interface.
currentModuleName = ichild.getModuleName();
}
private function reloadModule():void {
mod.unloadModule();
mod.loadModule();
}
="Current Module:"="{currentModuleName}"="Adjuster ID:"="myId"="Enter your ID"="Background Color:"mx:ColorPicker ="myColor"
selectedColor="0xFFFFFF"
change="reloadModule()"="Long Shot Insurance" fontSize="24"labelField="Select Module" module="AutoInsurance.swf"
ready="applyModuleSettings(event)"="reloadModule()" 接口文件,?
// modules/interfaceexample/IModuleInterface
package
{
import flash.events.IEventDispatcher;
public interface IModuleInterface extends IEventDispatcher {
function getModuleName():String;
function setAdjusterID(s:String):void;
function setBackgroundColor(n:Number):void;
}
}
Module模块文件
modules/interfaceexample/AutoInsurance.mxml implements="IModuleInterface"="p1"
title
backgroundColor="{bgcolor}"="myLabel"="ID: {adjuster}"
[Bindable]
private var adjuster:String;
[Bindable]
private var bgcolor:Number;
public function setAdjusterID(s:String):void {
adjuster = s;
}
public function setBackgroundColor(n:Number):void {
// Use a bindable property to set values of controls
// in the module. This ensures that the property will be set
// even if Flex applies the property after the module is
// loaded but before it is rendered by the player.
bgcolor = n;
// Don't do this. The backgroundColor style might not be set
// by the time the ModuleLoader triggers the READY
// event:
// p1.setStyle("backgroundColor",n);
}
public function getModuleName():String {
return "Auto Insurance";
}
>
(编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!