PureMVC, 快樂玩Part1
最近除了熱血的工作, 熱血的研究Progression, 當然還有熱血的PureMVC
好吧, 我承認這東西有一定的難度, 但上手後, 真的還滿方便的。
PureMVC是一種程式語言的框架, 不限於 AS3 , 官網有很多的版本可以任君選擇。
主要有三個概念
Model, Proxy
負責將數值變數存起來, 當數值被更改時, 就發送通知, 然後就什麼事也不做了。
View,Mediator
一個Mediator就對映一個View(視覺元件), 當View做了某件事情後, 發送通知。
Controller,Command
當 Mediator 被通知到後, 就執行事件做作好的Command
有了簡單概念後, 來開始試寫看看。
先下載 PureMVC AS3 standard 2.0.4版本

在這兒我們寫了一個小型的相本, 由 xml 管理, 畫面上有左、右鍵,二個動態文字
和一個要載入圖片用的Sprite。
奶小茶的習慣是先從Proxy來開始寫, 因為載入資料是最先要做的事情。
ListProxy.as
有了Proxy後,下一步來寫View跟Mediator
在這兒我們就只有一個主場景, 所以就準備一個ApplicationMediator.as
Mediator的工作就是觀查視覺元件的一切, 偵聽他的事件
更改他的數值, 就是他的保母啦。
ApplicationFacade, PureMVC 的總代理, 在這奶小茶使用的是 Standard版
所以只會有一個Facade, 如果要多個應用程式, 多個Facade的話,可以選用 MultiCore版本。
所有的 Proxies , Mediators 跟 Commands 註冊
他的程式碼很少, 都是固定的寫法。
啟動用的Command
StartupCommand.as
再來就是整個Clinet的主程式。
完成啦, 搞的大家都很不熟, 這就是PureMVC的精神呀
下次在專案上實作看看。
SourceCodeDownload
最近除了熱血的工作, 熱血的研究Progression, 當然還有熱血的PureMVC
好吧, 我承認這東西有一定的難度, 但上手後, 真的還滿方便的。
PureMVC是一種程式語言的框架, 不限於 AS3 , 官網有很多的版本可以任君選擇。
主要有三個概念
Model, Proxy
負責將數值變數存起來, 當數值被更改時, 就發送通知, 然後就什麼事也不做了。
View,Mediator
一個Mediator就對映一個View(視覺元件), 當View做了某件事情後, 發送通知。
Controller,Command
當 Mediator 被通知到後, 就執行事件做作好的Command
有了簡單概念後, 來開始試寫看看。
先下載 PureMVC AS3 standard 2.0.4版本

在這兒我們寫了一個小型的相本, 由 xml 管理, 畫面上有左、右鍵,二個動態文字
和一個要載入圖片用的Sprite。
奶小茶的習慣是先從Proxy來開始寫, 因為載入資料是最先要做的事情。
ListProxy.as
package milkmidi.puremvc.model {
import flash.events.Event;
import flash.net.URLLoader;
import flash.net.URLRequest;
import milkmidi.puremvc.model.vo.ListVO;
import org.puremvc.as3.interfaces.IProxy;
import org.puremvc.as3.patterns.proxy.Proxy;
public class ListProxy extends Proxy implements IProxy {
public static const NAME :String = "ListProxy";
//當 xml 載入完成後, 會發送notification
public static const DATA_LOAD_COMPLETE :String = 'dataLoadComplete';
//當 xml 索引值改變時
public static const MODEL_CHANGE :String = 'modelChange';
//當 ListProxy 被設定新值時
public static const SET_CURRENT_INDEX :String = 'setCurrentIndex';
private var _urlLdr :URLLoader = new URLLoader();
private var _xml :XML;
private var _currentIndex :uint = 0;
public function ListProxy(data:Object = null) {
super(NAME, data);
_urlLdr.addEventListener(Event.COMPLETE , completeHandler);
_urlLdr.load(new URLRequest('xml_data.xml'));
//載入 xml 。
}
private function completeHandler(e:Event):void {
_xml = XML(e.currentTarget.data);
//載入完成後,將得到的 xml 設定到 data裡。
setData( _xml );
sendNotification(DATA_LOAD_COMPLETE , data);
//記得要發通知喔。
}
public function setCurrentIndex(pIndex:uint):void {
_currentIndex = pIndex;
//設定索引值
if (_currentIndex < 0) _currentIndex = 0;
else if (_currentIndex >= length - 1)
_currentIndex = length - 1;
//判斷有沒有爆掉。
var _vo:ListVO = new ListVO();
_vo.img = currentImgURL;
_vo.title = currentTitle;
_vo.page = currentPage;
//將新的數值發送出去。
sendNotification(MODEL_CHANGE , _vo);
}
public function get length():uint { return _xml.item.length(); }
public function get currentImgURL():String { return _xml.item[currentIndex].img; }
public function get currentTitle():String { return _xml.item[currentIndex].title; }
public function get currentPage():String { return (_currentIndex + 1) +'/' + length; }
public function get currentIndex():uint { return _currentIndex; }
}
}
//在這兒也準備一個VO(ValueObject), 方便給大家使用。
ListVO.as
package milkmidi.puremvc.model.vo {
public class ListVO {
public var title:String = '';
public var img :String = '';
public var page :String = '';
public function ListVO() {
}
}
}
有了Proxy後,下一步來寫View跟Mediator
在這兒我們就只有一個主場景, 所以就準備一個ApplicationMediator.as
Mediator的工作就是觀查視覺元件的一切, 偵聽他的事件
更改他的數值, 就是他的保母啦。
package milkmidi.puremvc.view {
import flash.events.Event;
import milkmidi.puremvc.model.ListProxy;
import milkmidi.puremvc.model.vo.ListVO;
import org.puremvc.as3.interfaces.IMediator;
import org.puremvc.as3.interfaces.INotification;
import org.puremvc.as3.patterns.mediator.Mediator;
import milkmidi.puremvc.view.*;
public class ApplicationMediator extends Mediator implements IMediator {
// Cannonical name of the Mediator
public static const NAME:String = "ApplicationMediator";
public function ApplicationMediator(viewComponent:Object) {
super(NAME, viewComponent);
//偵聽主場景上的事件。
container.addEventListener('nextItem' , nextItemHandler);
container.addEventListener('prevItem' , prevItemHandler);
}
private function prevItemHandler(e:Event):void {
sendNotification( ListProxy.SET_CURRENT_INDEX , -1 );
//發送通知。
}
private function nextItemHandler(e:Event):void {
sendNotification( ListProxy.SET_CURRENT_INDEX , 1 );
//發送通知。
}
override public function getMediatorName():String {
return ApplicationMediator.NAME;
}
override public function listNotificationInterests():Array {
return [
ListProxy.DATA_LOAD_COMPLETE,
ListProxy.MODEL_CHANGE
];
//我只關心這些通知, 其他沒寫的就通通不管。
}
override public function handleNotification(note:INotification):void {
trace(facade.retrieveProxy( ListProxy.NAME));
//得到發送事件的 ListProxy 實體。
trace(note.getBody())
//得到發送通知時, 一起帶過來的數值
switch (note.getName()) {
case ListProxy.DATA_LOAD_COMPLETE:
sendNotification( ListProxy.SET_CURRENT_INDEX , 0 );
break;
case ListProxy.MODEL_CHANGE:
var _listVO:ListVO = note.getBody() as ListVO;
container.title_txt.text = _listVO.title + '';
container.numbers_txt.text = _listVO.page;
break;
default:
break;
}
}
private function get container():Main {
return viewComponent as Main;
//轉型用, 給自己看的。
}
}
}
//另一個ImageContainerMediator.as ,是觀查場景上的載入圖片用的Sprite, 寫法差不多,就不多介紹了。
ApplicationFacade, PureMVC 的總代理, 在這奶小茶使用的是 Standard版
所以只會有一個Facade, 如果要多個應用程式, 多個Facade的話,可以選用 MultiCore版本。
所有的 Proxies , Mediators 跟 Commands 註冊
他的程式碼很少, 都是固定的寫法。
package milkmidi.puremvc {
import flash.display.Stage;
import org.puremvc.as3.interfaces.IFacade;
import org.puremvc.as3.patterns.facade.Facade;
import milkmidi.puremvc.model.*;
import milkmidi.puremvc.view.*;
import milkmidi.puremvc.controller.*;
public class ApplicationFacade extends Facade implements IFacade {
// Notification name constants
public static const STARTUP:String = "startup";
public static function getInstance():ApplicationFacade {
if (instance == null) instance = new ApplicationFacade();
return instance as ApplicationFacade;
}
// Register commands with the controller
override protected function initializeController():void {
super.initializeController();
registerCommand(STARTUP, StartupCommand);
}
public function startup( pApp:Main ) : void {
sendNotification( STARTUP, pApp );
//這兒是用來啟動整個 PureMVC用的
}
}
}
啟動用的Command
StartupCommand.as
package milkmidi.puremvc.controller {
import milkmidi.puremvc.model.ListProxy;
import milkmidi.puremvc.view.ApplicationMediator;
import milkmidi.puremvc.view.ImageContainerMediator;
import org.puremvc.as3.interfaces.INotification;
import org.puremvc.as3.patterns.command.SimpleCommand;
public class StartupCommand extends SimpleCommand{
public function StartupCommand(){
super();
}
override public function execute(notification:INotification):void {
var _main:Main = notification.getBody() as Main;
facade.registerMediator( new ApplicationMediator( _main));
//注冊 Mediator
facade.registerMediator( new ImageContainerMediator( _main.container_mc));
//注冊 Mediator, 在這兒是用來載入外圖品片的容器。
facade.registerProxy( new ListProxy());
//注冊 Proxy。
facade.registerCommand( ListProxy.SET_CURRENT_INDEX , ModelChangeCommand);
//注冊 Command
}
}
}
//當要更改 ListProxy裡數值用的Command
package milkmidi.puremvc.controller {
import milkmidi.puremvc.model.ListProxy;
import org.puremvc.as3.interfaces.INotification;
import org.puremvc.as3.patterns.command.SimpleCommand;
import org.puremvc.as3.patterns.observer.Notification;
public class ModelChangeCommand extends SimpleCommand {
override public function execute(note:INotification):void {
var _listProxy :ListProxy = facade.retrieveProxy( ListProxy.NAME ) as ListProxy;
var _data :int = int(note.getBody());
_listProxy.setCurrentIndex(_listProxy.currentIndex + _data);
}
}
}
再來就是整個Clinet的主程式。
package {
import flash.display.MovieClip;
import flash.display.SimpleButton;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.text.TextField;
import milkmidi.puremvc.ApplicationFacade;
public class Main extends Sprite {
//場景上的元件
public var right_btn :SimpleButton;
public var left_btn :SimpleButton;
public var numbers_txt :TextField;
public var title_txt :TextField;
public var container_mc :MovieClip;
public function Main() {
right_btn.addEventListener(MouseEvent.CLICK , clickHandler);
left_btn.addEventListener(MouseEvent.CLICK , clickHandler);
ApplicationFacade.getInstance().startup( this );
//啟動PureMVC。
}
private function clickHandler(e:MouseEvent):void {
//左、右鍵只管發送事件, 就沒啦。
if (e.currentTarget == left_btn)
dispatchEvent(new Event('prevItem'));
else
dispatchEvent(new Event('nextItem'));
}
}
}
完成啦, 搞的大家都很不熟, 這就是PureMVC的精神呀
下次在專案上實作看看。
SourceCodeDownload
留言
相對程式碼也會比較多
如果只是小型的應用程式
不一定要用pureMVC
不果這東西這麼紅, 一定有他的道理在
到Google打,第一筆就是他的網站
在規劃程式的時候`,你會先在紙上做UML圖的規劃嗎?
通常都以功能面來規劃