2011年6月19日 星期日

【pureMVC】教學範例(二)

在第一篇我們已經將 UI 的元件分割出來後,就可以分別依照各個 Component 來建立 Mediator

以下先來看登入元件 "LoginForm.mxml" 的 Mediator -- LoginFormMediator.as


package org.view
{
    import org.view.component.LoginForm;
    import org.ApplicationFacade;
    import org.puremvc.as3.interfaces.IMediator;
    import org.puremvc.as3.interfaces.INotification;
    import org.puremvc.as3.patterns.mediator.Mediator;
    import flash.events.Event;
    import mx.controls.Alert;
    //須繼承 Mediator 並實作  IMediator 介面
    public class LoginFormMediator extends Mediator implements IMediator 
    {
        public static const NAME:String = "LoginFormMediator";
       
        public function LoginFormMediator(viewComponent:Object=null)
        {
            super(NAME, viewComponent);
            //註冊 LoginForm 的登入事件  "login", 當處發時呼叫  onLogin() 方法

            loginForm.addEventListener(ApplicationFacade.USER_LOGIN, onLogin);
        }
       
        private function onLogin(event:Event):void{
            //發出事件 (Notification)
            sendNotification( ApplicationFacade.USER_LOGIN, loginForm.account_text.text);
        }
       
        //覆寫 listNotificationInterests() 方法 ,表示LoginForm 所關心的事件
        public override function listNotificationInterests():Array
        {
            return [];
        }
        //處理 LoginForm 這個元件所關心的事件
        public override function handleNotification(notification:INotification):void
        {
        }
        //通常 Mediator 會提供一個 getter 方法取得該 Mediator 所對應的 Component
        private function get loginForm():LoginForm
        {
            return viewComponent as LoginForm; //回傳  LoginForm 這個 Component
        }
       
       
    }
}


接著再來看看呈現出結果的元件"TextArea.mxml" 的Mediator-- TextAreaMediator.as


package org.view
{
    import org.ApplicationFacade;
    import org.puremvc.as3.interfaces.IMediator;
    import org.puremvc.as3.interfaces.INotification;
    import org.puremvc.as3.patterns.mediator.Mediator;
    import org.view.component.TextArea;

    public class TextAreaMediator extends Mediator implements IMediator
    {
       
        public static const NAME:String = "TextAreaMediator";
        public function TextAreaMediator(viewComponent:Object=null)
        {
            super(NAME, viewComponent);
        }
       
        public override function listNotificationInterests():Array
        {
            //TextArea 這個元件關心 "登入失敗""登入成功"
            return [ApplicationFacade.LOGIN_FAIL, ApplicationFacade.LOGIN_SUCCESS];
        }
       
        public override function handleNotification(notification:INotification):void
        {
            switch(notification.getName()) //取得  notification 的事件名稱
            {
                case ApplicationFacade.LOGIN_SUCCESS: //登入成功
                       textArea.showAns.text = notification.getBody() as String;
                        break;
                case ApplicationFacade.LOGIN_FAIL:  //登入失敗
                        textArea.showAns.text = notification.getBody() as String;
                        break;
            }
        }

        private function get textArea():TextArea
        {
            return viewComponent as TextArea;
        }
    }
}



最後來看看 Command 的設計了,這邊先回顧一下在 ApplicationFacade.as 中的這段程式


//關聯了每個事件  (Notification) 所對應到的 Command
override protected function initializeController():void{
        super.initializeController();
        //註冊  START_UP Notification
        this.registerCommand(START_UP, AppCommand);
        //註冊  USER_LOGIN Notification
        this.registerCommand(USER_LOGIN, LoginCommand);
}


Command 只有在 Notification 發出時才會建立,通常 Command 建立時都會透過多個 Proxy

來處理事務,以下就來看看 START_UP 這個 Notification 發出時 AppCommand 做了什麼事


-- AppCommand.as



package org.controller

{
    import org.model.LoginFormProxy;
    import org.puremvc.as3.interfaces.INotification;
    import org.puremvc.as3.patterns.command.SimpleCommand;
    import org.view.LoginFormMediator;
    import org.view.TextAreaMediator;

    public class AppCommand extends SimpleCommand  //繼承 SimpleCommand
    {
        public function AppCommand()
        {
            super();
        }
        public override function execute(inote:INotification):void{
            //透過  INotification 取得 "Login.mxml" 這個 Component
            var _main:Login=inote.getBody() as Login; 
           
            //註冊所有的 Proxy -- "LoginFormProxy"
            facade.registerProxy(new LoginFormProxy());
           
            //註冊所有的 Mediator
            facade.registerMediator(new LoginFormMediator(_main.Loginform));
            facade.registerMediator(new TextAreaMediator(_main.ShowArea));
           
            /*這個 Command 比較特別的是, 它主要是將 pureMVC 的初始機制配置完成
               包含整個  AP 的所有 Proxy Mediator*/
        }

    }
}



接這就來關心當使用者輸入完帳號後按下按鈕後所觸發的 Command 到底做了什麼事情了


-- LoginCommand.as



package org.controller

{
    import org.puremvc.as3.interfaces.INotification;
    import org.puremvc.as3.patterns.command.SimpleCommand;
    import org.model.LoginFormProxy;
    import mx.controls.Alert;
   
    public class LoginCommand extends SimpleCommand
    {
        public function LoginCommand()
        {
            super();
        }
        public override function execute(inote:INotification):void{
           //透過 INotification 取得使用者輸入的帳號 
           var account:String = inote.getBody() as String;
           //取得  LoginFormProxy
           var loginProxy:LoginFormProxy = facade.retrieveProxy(LoginFormProxy.NAME) as LoginFormProxy;
           //執行登入的邏輯
           loginProxy.login(account);
          
        }
    }
}




接下來介紹 Proxy

沒有留言:

張貼留言