本部分,将学习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 | package org.rianotes.CairngormSample.events |
03 | import com.adobe.cairngorm.control.CairngormEvent; |
05 | import flash.events.Event; |
07 | public class LoginEvent extends CairngormEvent { |
09 | public static const LOGIN: String = "Login" ; |
11 | public var UserID: String ; |
12 | public var Password: String ; |
14 | public function LoginEvent(submittedUserID: String ,submittedPassword: String ) { |
16 | UserID = submittedUserID; |
17 | Password = submittedPassword; |
23 | override public function clone():Event { |
24 | return new LoginEvent(UserID,Password); |
接着我们做一个对应的Command,在commands文件夹下建一个LoginCommand.as类,让它实现ICommand接口。
LoginCommand:接收到LoginEvent后,所需要做的处理。这里就负责将ModelLocator的workflowState值做改变。
代码如下:
01 | package org.rianotes.CairngormSample.commands |
03 | import com.adobe.cairngorm.commands.ICommand; |
04 | import com.adobe.cairngorm.control.CairngormEvent; |
06 | import mx.controls.Alert; |
08 | import org.rianotes.CairngormSample.events.LoginEvent; |
09 | import org.rianotes.CairngormSample.model.ViewModelLocator; |
11 | public class LoginCommand implements ICommand { |
13 | public var model:ViewModelLocator = ViewModelLocator.getInstance(); |
15 | public function LoginCommand(){ |
19 | public function execute(event:CairngormEvent): void { |
20 | var loginEvent:LoginEvent = event as LoginEvent; |
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 | package org.rianotes.CairngormSample.control |
03 | import com.adobe.cairngorm.control.FrontController; |
06 | import org.rianotes.CairngormSample.events.*; |
07 | import org.rianotes.CairngormSample.commands.*; |
10 | public class SampleController extends FrontController { |
12 | public function SampleController() { |
16 | public function initialize(): 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 | import org.rianotes.CairngormSample.events.LoginEvent; |
07 | import org.rianotes.CairngormSample.model.ViewModelLocator; |
09 | private var model:ViewModelLocator = ViewModelLocator.getInstance(); |
11 | private function login(e:MouseEvent): void { |
12 | var loginEvent:LoginEvent = new LoginEvent(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 | import org.rianotes.CairngormSample.model.ViewModelLocator; |
11 | private var model: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}" > |