本部分,将学习Cairngorm的核心控制流程:
- Events:通过使用者操作View所产生的事件,或其他设计所产生的事件。
- Front Controller:Front Controller 用来注册Command与Events对应,接收Cairngorm Events并将他对应到Cairngorm Commands
- Command: 操作Cairngorm Business以及呼叫Cairngorm Delegates,这些回传所取得的资料Command会再将它更新到Model Locator 
首先介绍Cairngorm 的基本事件流程
![]()
使用者在操作View的过程会发出Event,然后由Front Controller来映射指派给对应的Command,Command做完运算处理后会更新ModelLocator的数据,然后View就会更新显示內容。
Front Controller在这里的角色有点像是Manager,专门负责嘴上工夫的,喔,不,其实是接收Event事件,然后指派给Command去做。
有点像是客户(user)跟业务(view)谈好,然后业务去告诉(Dispatch Event)Manager,然后Manager就很简单的说,丟给阿宅工程师(Command)去处理吧。阿宅工程师很辛苦的处理好后,把结果传给(Model),然后业务(view)就拿著结果去跟客户(User)讲,你看做好了,感觉怎样?
在实现这个项目上,我们首先建立好项目架构
在项目中建立events,control,commands三个文件夹。
![]()
在events文件夹中我们新增一个LoginEvent.as类,让它继承自CairngormEvent.
LoginEvent 让操作发出登陆事件
LoginEvent.as
| 01 | packageorg.rianotes.CairngormSample.events  | 
 
| 03 |     importcom.adobe.cairngorm.control.CairngormEvent;  | 
 
| 05 |     importflash.events.Event;  | 
 
| 07 |     publicclassLoginEvent extendsCairngormEvent {  | 
 
| 09 |         publicstaticconstLOGIN:String= "Login";  | 
 
| 11 |         publicvarUserID:String;  | 
 
| 12 |         publicvarPassword:String;  | 
 
| 14 |         publicfunctionLoginEvent(submittedUserID:String,submittedPassword:String) {  | 
 
| 16 |             UserID = submittedUserID;  | 
 
| 17 |             Password = submittedPassword;  | 
 
| 23 |         overridepublicfunctionclone():Event {  | 
 
| 24 |             returnnewLoginEvent(UserID,Password);  | 
 
  
接着我们做一个对应的Command,在commands文件夹下建一个LoginCommand.as类,让它实现ICommand接口。
LoginCommand:接收到LoginEvent后,所需要做的处理。这里就负责将ModelLocator的workflowState值做改变。
代码如下:
| 01 | packageorg.rianotes.CairngormSample.commands  | 
 
| 03 |     importcom.adobe.cairngorm.commands.ICommand;  | 
 
| 04 |     importcom.adobe.cairngorm.control.CairngormEvent;  | 
 
| 06 |     importmx.controls.Alert;  | 
 
| 08 |     importorg.rianotes.CairngormSample.events.LoginEvent;  | 
 
| 09 |     importorg.rianotes.CairngormSample.model.ViewModelLocator;  | 
 
| 11 |     publicclassLoginCommand implementsICommand {  | 
 
| 13 |         publicvarmodel:ViewModelLocator = ViewModelLocator.getInstance();  | 
 
| 15 |         publicfunctionLoginCommand(){  | 
 
| 19 |         publicfunctionexecute(event:CairngormEvent):void{  | 
 
| 20 |             varloginEvent:LoginEvent = event asLoginEvent;  | 
 
| 23 |             if(loginEvent.UserID=="eggant"&& loginEvent.Password=="eggant")  | 
 
| 25 |                 model.workflowState = ViewModelLocator.MAIN_SCREEN;  | 
 
| 28 |                 mx.controls.Alert.show("請確認帳號密碼是否正確!?");  | 
 
  
 
接着我们在control文件夹下新增一个SampleController.as类,让它继承自FrontController。
SampleController:负责将LoginEvent对应到LoginCommand,就是接收到LoginEvent就指派给LoginCommand。
代码如下:
| 01 | packageorg.rianotes.CairngormSample.control  | 
 
| 03 |     importcom.adobe.cairngorm.control.FrontController;  | 
 
| 06 |     importorg.rianotes.CairngormSample.events.*;  | 
 
| 07 |     importorg.rianotes.CairngormSample.commands.*;  | 
 
| 10 |     publicclassSampleController extendsFrontController {  | 
 
| 12 |         publicfunctionSampleController() {  | 
 
| 16 |         publicfunctioninitialize():void{  | 
 
| 22 |             this.addCommand( LoginEvent.LOGIN, LoginCommand);  | 
 
  
 
然后我们在LoginView.mxml作如下的修改,使用者点击Login Button就会dispatch LoginEvent
代码如下:
| 01 | <?xml version="1.0"encoding="utf-8"?>  | 
 
| 03 | horizontalAlign="right"xmlns:components="org.rianotes.CairngormSample.view.components.*">  | 
 
| 06 |             importorg.rianotes.CairngormSample.events.LoginEvent;  | 
 
| 07 |             importorg.rianotes.CairngormSample.model.ViewModelLocator;  | 
 
| 09 |             privatevarmodel:ViewModelLocator = ViewModelLocator.getInstance();  | 
 
| 11 |             privatefunctionlogin(e:MouseEvent):void{  | 
 
| 12 |                 varloginEvent:LoginEvent = newLoginEvent(ti_UserID.text,ti_Password.text);  | 
 
| 13 |                 loginEvent.dispatch();      | 
 
| 18 |     <mx:Form borderStyle="solid"width="100%">  | 
 
| 19 |         <mx:FormItem label="UserID :"width="100%">  | 
 
| 20 |              <mx:TextInput id="ti_UserID"width="100%"/>  | 
 
| 23 |         <mx:FormItem label="Password: "width="100%">  | 
 
| 24 |             <mx:TextInput id="ti_Password"width="100%"/>  | 
 
| 28 |     <mx:Button label="Login"click="login(event)"/>  | 
 
  
 
最后在Main.mxml中加入SampleController
代码如下:
| 01 | <?xml version="1.0"encoding="utf-8"?>  | 
 
| 04 |  xmlns:view="org.rianotes.CairngormSample.view.*" | 
 
| 05 |  layout="absolute"xmlns:control="org.rianotes.CairngormSample.control.*">  | 
 
| 09 |             importorg.rianotes.CairngormSample.model.ViewModelLocator;  | 
 
| 11 |             privatevarmodel:ViewModelLocator = ViewModelLocator.getInstance();  | 
 
| 15 |     <!--Cairngorm:FrontController :讓app中擁有SampleController-->  | 
 
| 16 |     <control:SampleController id="controller"/>  | 
 
| 18 |     <mx:ViewStack id="vsMain"width="100%"height="100%"selectedIndex="{model.workflowState}">    |