显示结构
下图是RssReader的显示结构。可以发现,除了可视化组件(绿色)外,非可视化组件(红色)也用mxml的方式组装到整个Application中。这样做的目的是为了更好的利用Flex中的事件传播机制。

事件流
下面看一下RssReader初始化时的事件流。(其他的事件流可以用同样的方法进行分析)

URI中监听了creationComplete事件。当创建URI完成后,会调用handleCreationComplete方法,设置的URL,然后再调用CairngormEventDispatcher的dispatch方法,发布自定义的GetFeedEvent事件。
代码如下:
<!--l version="1.0" encoding="utf-8--> <?xml version="1.0" encoding="utf-8"?> <mx:HBox xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="handleCreationComplete()"> <mx:Script> <![CDATA[ import com.nagpals.flexrssreader.events.GetFeedEvent; import com.adobe.cairngorm.control.CairngormEventDispatcher; import com.nagpals.flexrssreader.model.RSSReaderModelLocator; [Bindable] private var model : RSSReaderModelLocator = RSSReaderModelLocator.getInstance(); private function geturi(selecteduri:String):void{ CairngormEventDispatcher.getInstance().dispatchEvent(new GetFeedEvent(selecteduri)); } private function handleCreationComplete():void{ model.feedURI = "http://news.com.com/8300-10784_3-7.xml"; geturi(model.feedURI); } ]]> </mx:Script> <mx:Label text="Enter URL for an RSS feed" fontSize="12" paddingTop="4" fontWeight="bold"/> <mx:TextInput id="uritext" width="400" text="{model.feedURI}" fontSize="12"/> <mx:Button id="uributton" label="Get Feed" click="geturi(uritext.text)" fontSize="12"/> </mx:HBox> |
2. RSSReaderController中注册了GetFeedEvent的监听器。会接收到FlashPlayer分发的事件,并根据事先的定义调用GetFeedCommand进行处理。
package com.nagpals.flexrssreader.control...{ import com.adobe.cairngorm.control.FrontController; import com.nagpals.flexrssreader.commands.*; import com.nagpals.flexrssreader.events.*; public class RSSReaderController extends FrontController...{ public function RSSReaderController()...{ this.initialize(); } private function initialize() : void...{ this.addCommand(RSSReaderController.GET_FEED,GetFeedCommand); this.addCommand(RSSReaderController.SELECT_ITEM,SelectItemCommand); } /**//* ------------------------------------------------- */ public static const GET_FEED : String = "getFeed"; public static const SELECT_ITEM : String = "selectItem"; } } |
3.GetFeedCommand调用business.GetFeedDelegate处理逻辑,GetFeedDelegate通过HTTPService获取RSS数据后将结果返回给GetFeedCommand。代码如下:
public class GetFeedCommand implements ICommand, IResponder...{ private var delegate : GetFeedDelegate; private var model : RSSReaderModelLocator = RSSReaderModelLocator.getInstance(); public function GetFeedCommand()...{ delegate = new GetFeedDelegate(this); } public function execute( event : CairngormEvent ) : void...{ var feedEvent : GetFeedEvent = GetFeedEvent( event ); model.feedURI = feedEvent.selecteduri; delegate.getFeed(); } public function result( event : Object) : void...{ model.feedVOList = event.result.rss.channel.item as ArrayCollection; model.feedTitle = StringUtil.trim(event.result.rss.channel.title); model.feedTitleLink = StringUtil.trim(event.result.rss.channel.link); } public function fault( event : Object ) : void...{ mx.controls.Alert.show("Error in getting feed: " + event.message); } } |
4. 如果正常返回结果,GetFeedCommand会更新作为model的RSSReaderModelLocator中的数据。而RSSReaderModelLocator声明为[Bindable],当数据发生变化时会发出“propertyChange”事件。
(关于数据绑定的内容,请参考flex事件机制1:事件源)。
5. FlashPlayer接收到propertyChange事件后,会分发给所有绑定到model的组件,这些组件将自动更新数据。至此,整个初始化的过程就执行完毕。