Cairngorm框架实例
注明:本实例代码出自《Flex 从入门到精通》 聂晓霞编著,对教材代码略有修改以便适用于Flex4版本。 ? ? ? ? 实例为查询天气预报的系统,基于Cairngorm框架结构,远程调用一个公用的Web Services网站的数据,将信息以数据和图标显示出来。对于Cairngorm应用框架,分为四大模块(模型、视图、控制、服务),对于其内在的原理便不再赘述,下图可清晰分析其工作方式: ? ? ? ? ? 本实例的文件和程序流程图如下图,可方便了解项目的整体布局和执行过程: ? ? ? ? 在myeclipes中建立的flex项目文件结构如下: CityInfoVO.as: package com.weather.example.vo //定义返回的城市信息所使用的值对象 { import com.adobe.cairngorm.vo.ValueObject; [Bindable] public class CityInfoVO implements ValueObject { public var cityName :String = ""; //返回结果的城市名 public var stateName :String = ""; //返回结果的州名 public var latitude :String = ""; //返回结果纬度 public var longitude :String = ""; //返回结果经度 public var zipcode :String = ""; //返回结果邮编 } }QueryItemVO.as package com.weather.example.vo //定义查询数值使用的值对象 { import com.adobe.cairngorm.vo.ValueObject; [Bindable] public class QueryItemVO implements ValueObject { public var cityname:String = ""; //查询城市名 public var zipcode:String = ""; //查询邮政编码 } }CityInfoPanel.mxml <?xml version="1.0" encoding="utf-8"?> <s:Panel xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:view="com.weather.example.view.*" horizontalCenter="center"> <s:layout> <s:BasicLayout/> </s:layout> <fx:Declarations> <!-- 将非可视元素(例如服务、值对象)放在此处 --> </fx:Declarations> <fx:Script> <![CDATA[ import com.adobe.cairngorm.control.CairngormEventDispatcher; import com.weather.example.event.GetWeatherByCityEvent; import com.weather.example.model.ModelLocator; import com.weather.example.vo.*; //使用模型定位器来绑定结果信息到用户界面上 [Bindable] public var model:ModelLocator = ModelLocator.getInstance(); ]]> </fx:Script> <mx:Form id="loginForm"> <mx:FormItem label="城市名称:"> <s:TextInput id="cityname" minWidth="100" text="{model.getWeather.cityInfoVO.cityName}"/> </mx:FormItem> <mx:FormItem label="州名:"> <s:TextInput id="statename" minWidth="100" text="{model.getWeather.cityInfoVO.stateName}"/> </mx:FormItem> <mx:FormItem label="邮编:"> <s:TextInput id="zipcode" minWidth="100" text="{model.getWeather.cityInfoVO.zipcode}"/> </mx:FormItem> <mx:FormItem label="纬度:"> <s:TextInput id="latitude" minWidth="100" text="{model.getWeather.cityInfoVO.latitude}"/> </mx:FormItem> <mx:FormItem label="经度:"> <s:TextInput id="longitude" minWidth="100" text="{model.getWeather.cityInfoVO.longitude}"/> </mx:FormItem> </mx:Form> </s:Panel> QueryPanel.mxml <?xml version="1.0" encoding="utf-8"?> <s:Panel xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:view="com.weather.example.view" title="输入咨询信息" horizontalCenter="center" width="254" height="251"> <s:layout> <s:BasicLayout/> </s:layout> <fx:Declarations> <!-- 将非可视元素(例如服务、值对象)放在此处 --> </fx:Declarations> <fx:Script> <![CDATA[ import com.adobe.cairngorm.control.CairngormEventDispatcher; import com.weather.example.event.GetWeatherByCityEvent; import com.weather.example.model.ModelLocator; import com.weather.example.vo.QueryItemVO; [Bindable] private var model:ModelLocator = ModelLocator.getInstance(); //查询天气函数 public function queryWeather():void{ var queryItemVO:QueryItemVO = new QueryItemVO(); queryItemVO.cityname = cityname.text; queryItemVO.zipcode = zipcode.text; model.getWeather.queryItemVO = queryItemVO; var event:GetWeatherByCityEvent = new GetWeatherByCityEvent(queryItemVO); CairngormEventDispatcher.getInstance().dispatchEvent(event); } //清除输入信息的函数 private function clear():void{ cityname.text = ""; zipcode.text = ""; } ]]> </fx:Script> <mx:Text text="请填写其中一项查询数据,如果输入两项参数,查询以邮编为主" color="#1261CD" width="180" height="50" x="39" y="1"/> <mx:Form id="loginForm" x="10" y="53" height="91"> <!--输入城市名称的文本输入框--> <mx:FormItem label="城市名称:"> <s:TextInput minWidth="100" id="cityname" enter="queryWeather()"/> </mx:FormItem> <!--邮编输入框--> <mx:FormItem label="邮编:"> <s:TextInput minWidth="100" id="zipcode" enter="queryWeather()"/> </mx:FormItem> </mx:Form> <s:Label text="{model.getWeather.statusMessage}" color="#CD2812"/> <!--控制按钮触发查询和清除的函数--> <mx:ControlBar horizontalAlign="right" x="55" y="148" width="174" height="51"> <s:Button label="清空" click="clear()"/> <s:Button label="查询" enabled="{!model.getWeather.isPending}" click="queryWeather()"/> </mx:ControlBar> </s:Panel>WeatherResultChart.mxml: <?xml version="1.0" encoding="utf-8"?> <mx:VBox xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" width="400" height="300"> <fx:Declarations> <!-- 将非可视元素(例如服务、值对象)放在此处 --> </fx:Declarations> <fx:Script> <![CDATA[ import com.weather.example.model.ModelLocator; [Bindable] public var model :ModelLocator = ModelLocator.getInstance(); ]]> </fx:Script> <!--使用折线图显示温度曲线信息--> <mx:LineChart id="myChart" dataProvider="{model.getWeather.TemperatureList}" showDataTips="true" width="100%" height="100%"> <!--X坐标的数据序列--> <mx:horizontalAxis> <mx:CategoryAxis dataProvider="{model.getWeather.TemperatureList}" categoryField="Day"/> </mx:horizontalAxis> <!--Y坐标的数据序列--> <mx:series> <mx:LineSeries yField="MaxTemperatureC" displayName="最高摄氏温度"/> <mx:LineSeries yField="MinTemperatureC" displayName="最低摄氏温度"/> <mx:LineSeries yField="MaxTemperatureF" displayName="最高华氏温度"/> <mx:LineSeries yField="MinTemperatureF" displayName="最低华氏温度"/> </mx:series> </mx:LineChart> <!--Legend的数据源--> <mx:Legend dataProvider="{myChart}"/> </mx:VBox> WeatherResultPanel.mxml <?xml version="1.0" encoding="utf-8"?> <mx:Canvas xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" width="400" height="300"> <fx:Declarations> <!-- 将非可视元素(例如服务、值对象)放在此处 --> </fx:Declarations> <fx:Script> <![CDATA[ import com.weather.example.model.ModelLocator; [Bindable] public var model :ModelLocator = ModelLocator.getInstance(); ]]> </fx:Script> <!--使用AdvancedDataGrid显示信息--> <mx:AdvancedDataGrid dataProvider="{model.getWeather.weatherDataList}" variableRowHeight="true" width="100%" height="100%"> <!--使用AdvancedDataGrid的groupeColumns功能来显示不同单位的温度--> <mx:groupedColumns> <mx:AdvancedDataGridColumn headerText="日期" dataField="Day" width="200"/> <!--使用条目渲染器显示天气图标--> <mx:AdvancedDataGridColumn headerText="天气"> <mx:itemRenderer> <fx:Component> <mx:HBox horizontalAlign="left" paddingLeft="30" paddingRight="0" verticalAlign="middle" horizontalScrollPolicy="off"> <mx:Image source="{data.WeatherImage}"/> </mx:HBox> </fx:Component> </mx:itemRenderer> </mx:AdvancedDataGridColumn> <!--使用高级数据栅格的ColumnGroup来显示摄氏和华氏不同单位的最高温度--> <mx:AdvancedDataGridColumnGroup headerText="最高温度"> <mx:AdvancedDataGridColumn headerText="摄氏" dataField="MaxTemperatureC"/> <mx:AdvancedDataGridColumn headerText="华氏" dataField="MaxTemperatureF"/> </mx:AdvancedDataGridColumnGroup> <!--使用高级数据栅格的ColumnGroup来显示摄氏和华氏不同单位的最低温度--> <mx:AdvancedDataGridColumnGroup headerText="最低温度"> <mx:AdvancedDataGridColumn headerText="摄氏" dataField="MinTemperatureC"/> <mx:AdvancedDataGridColumn headerText="华氏" dataField="MinTemperatureF"/> </mx:AdvancedDataGridColumnGroup> </mx:groupedColumns> </mx:AdvancedDataGrid> </mx:Canvas>GetWeather.as package com.weather.example.model //具体的数据服务 { import com.weather.example.vo.*; import mx.collections.ArrayCollection; public class GetWeather { //查询信息对象 [Bindable] public var queryItemVO :QueryItemVO = new QueryItemVO(); //城市信息对象 [Bindable] public var cityInfoVO :CityInfoVO = new CityInfoVO(); //当前状态信息 [Bindable] public var statusMessage :String = ""; //是否查询按钮被激活或禁用 [Bindable] public var isPending :Boolean = false; //城市信息数组集合 [Bindable] public var cityDataList:ArrayCollection = new ArrayCollection(); //天气信息数组集合 [Bindable] public var weatherDataList:ArrayCollection = new ArrayCollection(); //温度信息数组集合 [Bindable] public var TemperatureList:ArrayCollection = new ArrayCollection(); } } ModelLocator.as package com.weather.example.model { import com.adobe.cairngorm.model.ModelLocator; [Bindable] public class ModelLocator implements com.adobe.cairngorm.model.ModelLocator { private static var modelLocator :com.weather.example.model.ModelLocator; //定义Instance 模型定位器 public static function getInstance():com.weather.example.model.ModelLocator{ if(modelLocator == null) modelLocator = new com.weather.example.model.ModelLocator(); return modelLocator; } public function ModelLocator() { if(com.weather.example.model.ModelLocator.modelLocator!=null) throw new Error("Only one ModelLocator Instance shoule be instantiated"); } //定义定位器中的变量 public var getWeather:GetWeather = new GetWeather(); } }GetWeatherByCityEvent.as package com.weather.example.event { import com.adobe.cairngorm.control.CairngormEvent; import com.weather.example.vo.QueryItemVO; import com.weather.example.control.GetWeatherByCityControl; public class GetWeatherByCityEvent extends CairngormEvent { public var queryItemVO:QueryItemVO; public function GetWeatherByCityEvent(queryItemVO:QueryItemVO) { super(GetWeatherByCityControl.EVENT_QUERY); this.queryItemVO = queryItemVO; } } } GetWeatherByCityControl.as package com.weather.example.control { import com.adobe.cairngorm.control.FrontController; import com.weather.example.commands.GetWeatherByCityCommand; import com.weather.example.event.GetWeatherByCityEvent; public class GetWeatherByCityControl extends FrontController { public function GetWeatherByCityControl() { addCommand(GetWeatherByCityControl.EVENT_QUERY,GetWeatherByCityCommand); } public static const EVENT_QUERY:String = "query"; } }GetWeatherByCityCommand.as package com.weather.example.commands //实现Command 和IResponder 类,具体执行查询命令 //处理业务逻辑,调用Delegates,更新服务定位器中存储的对象和变量 { import com.adobe.cairngorm.commands.Command; import com.adobe.cairngorm.control.CairngormEvent; import com.weather.example.business.ServicesDelegate; import com.weather.example.event.GetWeatherByCityEvent; import com.weather.example.model.ModelLocator; import mx.collections.ArrayCollection; import mx.rpc.IResponder; import mx.rpc.events.FaultEvent; import mx.utils.ObjectProxy; public class GetWeatherByCityCommand implements Command,IResponder { private var model:ModelLocator = ModelLocator.getInstance(); public function execute(event:CairngormEvent):void { //调用委托方法 model.getWeather.isPending = true; var delegate:ServicesDelegate = new ServicesDelegate(this); var queryEvent:GetWeatherByCityEvent = GetWeatherByCityEvent(event); delegate.query(queryEvent.queryItemVO); } public function result(event:Object):void{ //得到远程结果 var resultAry:Object = Object(event.result); //处理天气信息 var ary:ArrayCollection = new ArrayCollection(); //判断是否得到了返回结果 if(resultAry.Details==null){//当返回结果为null时,显示相应的提示信息 model.getWeather.statusMessage = "请填写正确的查询信息"; model.getWeather.isPending = false; } else{//得到正确的结果 ary = ArrayCollection(resultAry.Details); //将温度数据存储到一个数组集合中 ary.removeItemAt(ary.length - 1); // 去掉最后一个空数据 model.getWeather.weatherDataList = ary; //将天气数据赋值给模型控制器相应的变量 model.getWeather.TemperatureList = new ArrayCollection(); for each(var temp:Object in ary){//获取数组集合中每天的温度值 if(temp!= null){ var obj:ObjectProxy = new ObjectProxy(); obj.Day = temp.Day; obj.MaxTemperatureC = temp.MaxTemperatureC; obj.MinTemperatureC = temp.MinTemperatureC; obj.MaxTemperatureF = temp.MaxTemperatureF; obj.MinTemperatureF = temp.MinTemperatureF; model.getWeather.TemperatureList.addItem(obj); } } //将查询的邮编赋值给模型控制器中城市信息的值对象 if(model.getWeather.queryItemVO != null && model.getWeather.queryItemVO.zipcode !=""){ model.getWeather.cityInfoVO.zipcode = model.getWeather.queryItemVO.zipcode; } //将获取的结果赋值给模型控制器中城市信息的值对象 model.getWeather.cityInfoVO.cityName = resultAry.PlaceName; model.getWeather.cityInfoVO.stateName = resultAry.StateCode; model.getWeather.cityInfoVO.latitude = resultAry.Latitude; model.getWeather.cityInfoVO.longitude = resultAry.Longitude; model.getWeather.isPending = false; } } //处理错误结果 public function fault(event:Object):void{ //得到错误信息 var faultEvent:FaultEvent = FaultEvent(event); model.getWeather.statusMessage = "远程服务错误"; model.getWeather.isPending = false; } } } ServicesDelegate.as package com.weather.example.business { import com.adobe.cairngorm.business.Responder; import com.adobe.cairngorm.business.ServiceLocator; import com.weather.example.model.ModelLocator; import com.weather.example.vo.QueryItemVO; import mx.rpc.IResponder; public class ServicesDelegate { private var responder:IResponder; private var service:Object; private var model:ModelLocator = ModelLocator.getInstance(); //服务委托 public function ServicesDelegate(responder:IResponder){ this.service = ServiceLocator.getInstance().getWebService("WeatherServices"); this.responder = responder; } //查询函数 public function query(queryItemVO:QueryItemVO):void{ if(queryItemVO.zipcode!=""){//如果邮编不为空,则使用邮编来查询 model.getWeather.statusMessage = ""; //调用远程Web Services的GetWeatherByZipCode的操作 var call:Object = service.GetWeatherByZipCode(queryItemVO.zipcode); call.addResponder(responder); } else if(queryItemVO.cityname!=""){//如果邮编为空,使用城市名查询 model.getWeather.statusMessage = ""; var call2:Object = service.GetWeatherByPlaceName(queryItemVO.cityname); call2.addResponder(responder); } else{//如果都为空,显示相应的错误信息 model.getWeather.statusMessage = "请至少填写其中一项查询信息"; model.getWeather.isPending = false; } } } } Services.mxml <?xml version="1.0" encoding="utf-8"?> <cairngorm:ServiceLocator xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:cairngorm="com.adobe.cairngorm.business.*"> <!--定义web service 的各项参数和方法--> <mx:WebService id="WeatherServices" wsdl="http://www.webservicex.net/WeatherForecast.asmx?wsdl" useProxy="false" showBusyCursor="true"> <mx:operation name="GetWeatherByPlaceName"/> <mx:operation name="GetWeatherByZipCode"/> </mx:WebService> </cairngorm:ServiceLocator> 程序运行结果如图(出现远程服务错误...) 本文版权归作者所有,欢迎转载学习,但需在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |