Mate-Tag Base Framework
Mate will become another hot pot in Flex area . It use configuration to call the service and handle the event. It also uses configuration to update the Bindable object. Somehow The Mate is The “springframework” in Flex Area.
There are two architecture level diagrams of Mate. One is from Yakov Fain of Farata Systems, Another is from Mate funder company ASFusion. I like the later one:
Lets use mate to develop the buddyList application
1.Create the core component of mate —-EventMap.
The EventMap is the heart of mate it glues all the other component and control the process:
BuddyListEventMap.mxml:
<?xml version=”1.0″ encoding=”utf-8″?>
<EventMap
xmlns=”http://mate.asfusion.com/”
xmlns:mx=http://www.adobe.com/2006/mxml>
</EventMap>
I will add the related code later. Now we need tell the main app that initialize the EventMap:
Flex_Mate.mxml:
<?xml version=”1.0″ encoding=”utf-8″?>
<mx:Application
xmlns:map=”com.ny.flex.mate.map.*” xmlns:views=”com.ny.flex.mate.views.*” xmlns:mx=”http://www.adobe.com/2006/mxml” layout=”absolute“>
<mx:Script>
<![CDATA[
[
Bindable
]
public var
viewStackSelectedIndex :int = 0;
]]>
</mx:Script>
<map:BuddyListEventMap/>
<mx:HBox horizontalAlign=”center” verticalAlign=”top” width=”100%” height=”100%” y=”0” x=”0“>
<mx:ViewStack id=”viewStack” resizeToContent=”true” selectedIndex=”{viewStackSelectedIndex}” >
<views:LoginView />
<views:BuddyListView/>
</mx:ViewStack>
</mx:HBox>
</mx:Application>
2. Create the LoginView :
<?xml version=”1.0″ encoding=”utf-8″?>
<mx:Panel
xmlns:mx=”http://www.adobe.com/2006/mxml” layout=”absolute” width=”300” height=”200” horizontalAlign=”center” verticalAlign=”middle” title=”Flex Cirngorm Login“>
<mx:Script>
<![CDATA[
import
com.ny.flex.mate.event.LoginEvent;
import
com.ny.flex.mate.vo.User;
import
mx.validators.Validator;
private function login():void
{
if
(Validator.validateAll(validators).length == 0){
var loginUser:User = new
User();
loginUser.userName=username.text;
loginUser.password=password.text;
var loginEvent:LoginEvent = new
LoginEvent(LoginEvent.LOGIN);
loginEvent.loginUser = loginUser;
dispatchEvent(loginEvent);
}
}
]]>
</mx:Script>
<!– Validators–>
<mx:Array id=”validators“>
<mx:StringValidator id=”userNameValidator” source=”{username}” property=”text” required=”true“/>
<mx:StringValidator id=”passwordValidator” source=”{password}” property=”text” required=”true” />
</mx:Array>
<mx:Form
id=”loginForm” x=”0” y=”0“>
<mx:FormItem label=”Username:” >
<mx:TextInput id=”username” />
</mx:FormItem>
<mx:FormItem label=”Password:” >
<mx:TextInput id=”password” displayAsPassword=”true” />
</mx:FormItem>
<mx:FormItem direction=”horizontal” verticalGap=”15” paddingTop=”5” width=”170“>
<mx:Button id=”loginBtn” label=”Login” click=”login()”/>
</mx:FormItem>
</mx:Form>
</mx:Panel>
See the action method above the LoginEvent is dispatched. Now create the LoginEvent:
package
import
com.ny.flex.mate.vo.User;
import
flash.events.Event;
public class LoginEvent extends
Event
{
public static const LOGIN:String = “login”
;
public var
loginUser:User;
public function LoginEvent(type:String, bubbles:Boolean=true, cancelable:Boolean=false
)
{
super
(type, bubbles, cancelable);
}
}
}
com.ny.flex.mate.event
{
The “bubbles” has to be “true”, it makes EventMap can handle it. The magic of mate comes in the EventMap . The LoginEvent can handle by tag :
…..
<EventHandlers type=”{LoginEvent.LOGIN}“>
<RemoteObjectInvoker destination=”flexmvcRO” method=”authenticate”
arguments=”{event.loginUser}“>
<resultHandlers>
<MethodInvoker generator=”{LoginService}”
method=”onResult_Authenticate”
arguments=”{resultObject}“/>
</resultHandlers>
</RemoteObjectInvoker>
</EventHandlers>
……
In the EvevntHandler , You can define the service call function(RemoteObjectInvoker here) . and It also define the result handler specify the service class ,method and arguments.
Lets see the LoginService object:
package
com.ny.flex.mate.service
{
import
com.ny.flex.mate.vo.User;
public class
LoginService
{
[
Bindable
]
public var
authUserName:String;
[
Bindable
]
public var
viewStackSelectedIndex:int ;
public function onResult_Authenticate(user:User):void
{
authUserName = user.userName;
viewStackSelectedIndex = 1;
}
}
}
The service class handle the result and make the return object bindable. now we need update target views. Another shine point of mate is Injecting the bindable object to the target view! you just need add another tag in EventMap class . (This is damn cool):
<Injectors target=”{BuddyListView}“>
<PropertyInjector targetKey=”authUserName” source=”{LoginService}”
sourceKey=”authUserName“/>
</Injectors>
<Injectors target=”{Flex_Mate}“>
<PropertyInjector targetKey=”viewStackSelectedIndex” source=”{LoginService}”
sourceKey=”viewStackSelectedIndex“/>
</Injectors>
You just need specify the target view, taget key , source service object and source key!
Finally lets define the target view :BuddyListView:
<?xml version=”1.0″ encoding=”utf-8″?>
<mx:Panel
xmlns:mx=”http://www.adobe.com/2006/mxml” title=”Buddy List of {authUserName}“ creationComplete=”getBuddyList()” width=”500” height=”320“>
<mx:Script>
<![CDATA[
import
mx.collections.ArrayCollection;
import
com.ny.flex.mate.event.GetBuddyListEvent;
[
Bindable
]
public var
authUserName:String;
[
Bindable
]
public var
buddyCollection:ArrayCollection;
private function getBuddyList():void
{
var getBuddyListEvent:GetBuddyListEvent = new
GetBuddyListEvent(GetBuddyListEvent.GET_BUDDY_LIST);
getBuddyListEvent.authUserName = authUserName;
dispatchEvent(getBuddyListEvent);
}
]]>
</mx:Script>
<mx:DataGrid id=”buddyList” dataProvider=”{buddyCollection}” borderStyle=”none” width=”100%” height=”100%” >
<mx:columns>
<mx:DataGridColumn dataField=”firstName” headerText=”First Name“/>
<mx:DataGridColumn dataField=”lastName” headerText=”Last Name“/>
</mx:columns>
</mx:DataGrid>
</mx:Panel>
Checkout the “{autherUsername}”, it comes from the LoginService.
You probably wonder about “buddyListCollection”. It means another around development:
Action–>Dispatch Event–>Config Handler–>create service–>Inject Bindable Object –>another Action….
All the other code is blow:
GetBuddyListEvent.as:
package
import
flash.events.Event;
public class GetBuddyListEvent extends
Event
{
public static const GET_BUDDY_LIST =“getAllFriends”
;
public var
authUserName:String;
public function GetBuddyListEvent(type:String, bubbles:Boolean=true, cancelable:Boolean=false
)
{
super
(type, bubbles, cancelable);
}
}
}
com.ny.flex.mate.event
{
BuddyService.as:
package
import
mx.collections.ArrayCollection;
public class
BuddyService
{
[
Bindable
]
public var
buddyList:ArrayCollection;
public function
onResult_GetBuddyList(buddies:ArrayCollection){
buddyList = buddies;
}
}
}
com.ny.flex.mate.service
{
The completely EventMap file: BuddyListEventMap.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
com.ny.flex.mate.event.BDbbdEvent;
import
com.ny.flex.mate.service.BuddyService;
import
com.ny.flex.mate.event.GetBuddyListEvent;
import
com.ny.flex.mate.views.BuddyListView;
import
com.ny.flex.mate.service.LoginService;
import
com.ny.flex.mate.event.LoginEvent;
]]>
</mx:Script>
<EventHandlers type=”{LoginEvent.LOGIN}“>
<RemoteObjectInvoker destination=”flexmvcRO” method=”authenticate” arguments=”{event.loginUser}“>
<resultHandlers>
<MethodInvoker generator=”{LoginService}” method=”onResult_Authenticate” arguments=”{resultObject}“/>
</resultHandlers>
</RemoteObjectInvoker>
</EventHandlers>
<EventHandlers type=”{GetBuddyListEvent.GET_BUDDY_LIST}“>
<RemoteObjectInvoker destination=”flexmvcRO” method=”{GetBuddyListEvent.GET_BUDDY_LIST}” arguments=”{event.authUserName}“>
<resultHandlers>
<MethodInvoker generator=”{BuddyService}” method=”onResult_GetBuddyList” arguments=”{resultObject}“/>
</resultHandlers>
</RemoteObjectInvoker>
</EventHandlers>
<Injectors target=”{BuddyListView}“>
<PropertyInjector targetKey=”authUserName” source=”{LoginService}” sourceKey=”authUserName“/>
<PropertyInjector targetKey=”buddyCollection” source=”{BuddyService}” sourceKey=”buddyList“/>
</Injectors>
<Injectors target=”{Flex_Mate}“>
<PropertyInjector targetKey=”viewStackSelectedIndex” source=”{LoginService}” sourceKey=”viewStackSelectedIndex“/>
</Injectors>
</EventMap>
Summary
I discussed flex development in last 5 blogs. What is the best choice ?
I think the central management will be NO1. choice for the small project. Because you dont need learn any new framework and you still get clear architecture .
For the mate and Cairngorm, Mate seems win the conpetition now. Because
For Cairngorm:
1. Cairngorm is too complicate and study cost is higher.
2. Cairngorm has some Junk code for my opionion, ie.frontcontrollerI.
For Mate,
1 . It is simpler than Cairngorm, and easier to study.
2. You get benefit from EventMap, Because you dont need write ther glue code between event and the service.
3.You get pain from EventMap. Just imagine you have 50 actions and 100 objects to bind. you have to put lots of configration stuff in your EventMap, Then EventMap become the disastor!
So if you have to use cairngorm use my solution Cairngorm without FrontContoller.
For the mate, if they can add the Meta Tag instead of the EventMap. i.e.:
[EventHadler ={name ="myHandler", serviceclass="myservice" result , taget ...}]
MateDispatch(myevent).
So you dont need config anything, I am waiting for this.
No comments yet.
Leave a comment
-
Archives
- July 2008 (6)
-
Categories
-
RSS
Entries RSS
Comments RSS