part1介紹過Mate架構跟流程,這次寫一個簡單範例來說明Mate的寫法
範例為使用DataGrid操作來自DataManager的資料。按此觀看範例
Main.mxml
同上次的架構,程式的進入點是Main.mxml,裡面只要宣告EventMap、ModelMap跟要使用的UI
<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" xmlns:maps="idv.gd.hellomate.maps.*" xmlns:view="idv.gd.hellomate.views.*" width="600" height="350"> <mx:Style source="assets/style.css"/> <maps:MainEventMap/> <maps:ModelMap/> <view:DataList/> </mx:Application>
DataList.mxml
DataList.mxml 為列表的UI,負責顯示、新增及刪除,在Mate架構中,UI的Domain Logic直接寫在mxml,或許會有點亂,但這種寫法也方便Mate做Data Binding
<!-- 部分程式碼 --> <!-- mate特有的Dispatcher,即使元件不在顯示列表或不可見,仍可送訊息給Mate --> <mate:Dispatcher id="deleteAllDispatcher" generator="{ListEvent}" type="{ListEvent.REMOVE_ALL}"> <!-- 可直接接收來自EventMap的回應 --> <mate:ResponseHandler type="deleteItemResponse" response="Alert.show('ok')"/> </mate:Dispatcher> <!-- 能監聽自己內部跟Mate事件 --> <mate:Listener type="{NavigationEvent.ADD_STATE}" receive="stateChangeHandler(event)"/> <mate:Listener type="{NavigationEvent.LIST_STATE}" receive="stateChangeHandler(event)"/> <mx:DataGrid id="myDG" x="10" y="10" width="560" height="215" dataProvider="{currentListAC}"> <mx:columns> <mx:DataGridColumn headerText="標題" dataField="title"/> <mx:DataGridColumn headerText="訊息" dataField="message"/> </mx:columns> </mx:DataGrid>
事件可由Mate的Dispatcher送出,也可使用原本的EventDispatcher,但事件的bubbles一定要為true,而<listener>的標籤可以聽到來自Mate的事件,但自己Bubbles上來的事件也會聽到,在設計時要注意
三種在Mate中傳事件的寫法:
一、使用<Dispatcher>:<mate:Dispatcher id="deleteAllDispatcher" generator="{ListEvent}" type="{ListEvent.REMOVE_ALL}">,用調用時呼叫 deleteAllDispatcher.generateEvent();
二、使用原生的EventDispatcher:this.dispatchEvent(new NavigationEvent(NavigationEvent.ADD_STATE));,由於事件bubble為true,EventMap可聽到事件
三、使用程式碼的Mate Dispatcher: var mateDispatcher:Dispatcher = new Dispatcher(); mateDispatcher.dispatchEvent(listEvent);
ListEvent.as
自定事件,寫法同一般Flash事件寫法,但為避免混淆,Mate建議在事件的常數後加上Class名,好讓事件不會重覆
public class ListEvent extends Event { //常數後加上Class名,避免名稱重覆 public static const DELETE:String = "deleteListEvent"; public static const REMOVE_ALL:String = "removeAllListEvent"; public static const ADD:String = "addListEvent"; public var item:ItemInfo; //bubbles要為true,給EventMap聽 public function ListEvent(type:String, bubbles:Boolean = true, cancelables:Boolean = false, item:ItemInfo = null) { super(type, bubbles, cancelables); this.item = item; } override public function clone():Event { return new ListEvent(type, bubbles, cancelable, item); } }
DataManager.mxml
為管理列表資料的Manager
public class DataManager { public var listArrayCollection:ArrayCollection; public function DataManager() { listArrayCollection = new ArrayCollection(); listArrayCollection.addItem(new ItemInfo("first item", "hello mate")); listArrayCollection.addItem(new ItemInfo("second item", "test")); } public function deleteItem(item:ItemInfo):void { if (listArrayCollection) listArrayCollection.removeItemAt(listArrayCollection.getItemIndex(item)); } public function deleteAllItem():void { if (listArrayCollection) listArrayCollection.removeAll(); } public function addItem(item:ItemInfo):void { if (listArrayCollection) listArrayCollection.addItem(item); } }
DataManager封裝了資料操作,這裡只外露一個listArrayCollection給外部View使用,也可把ModelManager做為資料物件跟View挷定,但要記得要給class設[Bindable],或自定Binding事件
MainEventMap.mxml
為Mate事件的中心,用以管理事件及專案的Business Logic
<?xml version="1.0" encoding="utf-8"?> <EventMap xmlns="http://mate.asfusion.com/" xmlns:mx="http://www.adobe.com/2006/mxml"> <mx:Script> <![CDATA[ import idv.gd.hellomate.events.*; import idv.gd.hellomate.business.DataManager; ]]> </mx:Script> <!-- 監聽Mate事件,可呼叫Manager執行方法(Manager只會被生成一次)--> <EventHandlers type="{ListEvent.DELETE}"> <MethodInvoker generator="{DataManager}" method="deleteItem" arguments="{event.item}"/> </EventHandlers> <EventHandlers type="{ListEvent.REMOVE_ALL}"> <MethodInvoker generator="{DataManager}" method="deleteAllItem"/> <!-- 回應訊息給呼叫者 --> <ResponseAnnouncer type="deleteItemResponse"/> </EventHandlers> <EventHandlers type="{ListEvent.ADD}"> <MethodInvoker generator="{DataManager}" method="addItem" arguments="{event.item}"/> <!-- 發送Navigation事件 --> <EventAnnouncer generator="{NavigationEvent}" type="{NavigationEvent.LIST_STATE}" /> </EventHandlers>
其中<EventHandlers>的標籤為註冊Event要觸發的事件,這裡能調用ModelManager的方法,並可直接回傳內容(<ResponseAnnouncer>)或是呼叫事件(<EventAnnouncer>)
ModelMap.mxml
<?xml version="1.0" encoding="utf-8"?> <EventMap xmlns="http://mate.asfusion.com/" xmlns:mx="http://www.adobe.com/2006/mxml"> <mx:Script> <![CDATA[ import idv.gd.hellomate.views.DataList; import idv.gd.hellomate.business.DataManager; ]]> </mx:Script> <!-- 注入資料,DataList生成時自動注入 --> <Injectors target="{DataList}" debug="true"> <PropertyInjector targetKey="currentListAC" source="{DataManager}" sourceKey="listArrayCollection"/> </Injectors> </EventMap>
ModelMap.mxml底層其實是EventMap,這裡分出來只是為了釐清架構。其中<Injectors>是很特殊的標籤,會在目標元件生成時自動把資料注入,且若是Bindable物件,之後就可靠物件自己更新,在寫法上很方便。
總結
這次只寫個簡單範例練習,由於Mate可用Data Binding,在寫法上會比PureMVC好寫很多,但實際上使用還是要看專案的複雜度,沒有人說那個MVC Framework是最好的,端看開發人員習慣那種架構。
這次的練習不夠完整,如果寫法或概念有錯還請指正,謝謝
0 意見 :: [教學]Mate Framework Part2
張貼留言