Home >
Let’s get this out of the way first thing. It’s Mah-tay, not M-eight. Like the drink, the creators of Mate, Nahuel Faronda and Laura Arguello, come from Argentina. If you’ve never tried Mate (the drink), you should - it’s tasty. If you’ve never tried Mate (the framework), well, that’s tasty, too, and you’re about to dig into a big bowl full. Sorry about that mixed metaphor there.
Mate is design to take advantage of MXML and regular old Flash events dispatched the regular way, not through the framework like Cairngorm or Swiz (although Swiz is open to regular event dispatching if you set it up yourself). In that way it’s like PureMVC. But Mate uses the fact that part of the framework is defined right at Application level to make the event-driven part of the framework very unobtrusive and easy.
Since it’s very unobtrusively event based (you’ll see what I mean in a bit) it allows you to make a very componentized application easily, and although of course you can use the classes from the framework in ActionScript form, you’ll be surprised at how much you can do right in MXML.
Let’s look at one of those green box things again. The Delegate is yellow to show that it’s optional.

So when a user interacts with the view, and event is fired. The EventMap, declared on the root application receives all events dispatched anywhere in the view as long as the bubbles property of the event is set to true. So the basic way of acting on some user input is to dispatch a custom event with the bubbles property set to true. This is how Mate is so unobtrusive. You don’t have to define event listeners all over the place, just define some code in the EventMap to catch certain types of events. The EventMap takes care of calling the service in simple situations, but it could delegate the service call to a delegate as well.
The EventMap could also fire off a command, Cairngorm style, if you like that way of doing things better. Mate is a very flexible framework. In fact, there are a lot more parts to Mate than are listed here and any of them could be used to do things a different way or to deal with exceptions. Mate’s documentation is particularly good and easy to use compared to the other frameworks, so have a look at it if you want.
To get data into the view, Mate either defines an IoC style Injector or simply dispatches an event with an EventAnnouncer and the view can use Mate’s Listener tag to be notified of these events. We’ll see both ways of doing things. Storing data in the model is delegated to objects that most of the examples call Managers. Some examples use a Manager to actually do service interaction. Again that’s up to you and how pure you want the model to be.
Ok, let’s start looking into how I did this application the Mate way.
Twitter Through A Bomba
The first Mate specific code in our app is on the root application.
twitteria_mate/src/twitteria_mate.mxml #21
<maps:MainEventMap />
The EventMap is central to any Mate application, so it’s defined early. Note that although we only have one, you can have as many as you want, so you can break things up as clean as you want them.
Each application defines its own EventMap, and ours is imaginatively called MainEventMap. There’s not a lot more to see on the application, so let’s look at logging in.
Logging In
Once again, hitting enter in the password field kicks off the login process. It calls the login method on LoginView.
twitteria_mate/src/com/insideria/twitteria/view/LoginView.mxml
#10-13 (formatted)
public function login():void {
var le:LoginEvent = new LoginEvent(
usernameText.text, passwordText.text
);
dispatchEvent(le);
}
We dispatch a LoginEvent and send along the username and password. Nothing framework specific. Let’s look at the LoginEvent.
twitteria_mate/src/com/insideria/twitteria/events/LoginEvent.as
#7-16 (formatted)
public static const LOG_IN:String = "login";
public var username:String;
public var password:String;
public function LoginEvent(username:String, password:String) {
super(LOG_IN, true, false);
this.username = username;
this.password = password;
}
First, we keep a constant on the event to make sure the type of the event is clear. We also have a place for the username and password payload. The super call is important. The arguments are ‘type’, ‘bubbles’, and ‘cancelable’. The type is our constant, and bubbles is set to true. That’s important because when an event bubbles it moves all the way to the top of the display object tree and anything in the tree can listen for it. The EventMap ultimately listens for this event.
twitteria_mate/src/com/insideria/twitteria/maps/MainEventMap.mxml
#13-16 (formatted)
<EventHandlers type="{LoginEvent.LOG_IN}" debug="true">
<ObjectBuilder
generator="{TwitterDelegate}"
constructorArguments="{[
event.username, event.password, scope.dispatcher
]}" />
<MethodInvoker
generator="{TwitterDelegate}"
method="loadTimeline" />
</EventHandlers>
Wow. There’s a lot going on here, so let’s break it down. The EventHandlers tag defines the actions to take for a certain type of event, designated in the type property. This corresponds to the constant in our LoginEvent, so this is the event handler for when that event bubbles up.
When that event gets caught, the first tag takes over. The ObjectBuilder tag creates an object of a certain type, which is set in the generator property. That can be either a fully qualified path as a string, or a class in a binding, like we have. The default behavior is to create an object of that type and keep a reference to it indexed by type. That means that any another object of that type is requested, the cached object will be returned. This is how Mate deals with the problem that Cairngorm deals with using singletons, that of keeping an instance of an object easy to get to.
The constructorArguments are, of course, how you pass in arguments to the class’ constructor. Here we pass in, from the incoming event, the username, password, and from the scope property of the EventMap, a dispatcher. Hopefully the event properties are clear enough to you. The dispatcher thing needs to be cleared up a bit though, I bet. What we’re going to do, since we don’t have a standard service to call, like a RemoteObject, WebService, or HTTPService, which all have invokers in Mate, is to have a delegate that dispatches events when things happen. To make that work with any Mate Listeners, which we’ll see in a bit, we need to dispatch the events through Mate. This dispatcher passed into the TwitterDelegate’s constructor lets us do that.
Next, we use a MethodInvoker tag to invoke a method on the TwitterDelegate, namely loadTimeline. The MethodInvoker uses the same generator style. Since the defaults are in place on the ObjectBuilder, the object that was built there will be reused here. In fact, We didn’t even really need to use the ObjectBuilder, because the generator in MethodInvoker would have cached the class too. That’s the default behavior of most of the tags used in the EventMap. Why did I use the ObjectBuilder then? Just to show it could be done and to make it explicit. Look, I’m trying to teach here.
That was a lot of explanation for two or three tags, so let’s say it in plain English. When the EventMap gets the LoginEvent, it builds a TwitterDelegate and caches the instance for whenever another TwitterDelegate is requested. Then we invoke loadTimeline on a TwitterDelegate, which uses the cached instance. Let’s see what happens in the delegate.
Loading The Timeline
Just like before, we decide on using the dummyData or not, and possibly call the Twitter service.
twitteria_mate/src/com/insideria/twitteria/business/TwitterDelegate.as
#33-42 (formatted)
public function loadTimeline():void {
if (useDummyData) {
var te:TwitterEvent = new TwitterEvent(
TwitterEvent.ON_FRIENDS_TIMELINE_RESULT
);
te.data = getDummyData();
friendsTimelineLoaded(te);
} else {
twitterService.loadFriendsTimeline(username);
}
}
And either way, the callback is executed.
twitteria_mate/src/com/insideria/twitteria/business/TwitterDelegate.as
#53-56 (formatted)
private function friendsTimelineLoaded(te:TwitterEvent):void {
var e:TimelineReceivedEvent =
new TimelineReceivedEvent(te.data as Array);
dispatcher.dispatchEvent(e);
}
This time it’s different, though, and we get together a TimelineReceivedEvent with the array of tweets and dispatch it through the dispatcher we got from the MainEventMap when the delegate was constructed.
The MainEventMap is listening for that kind of event:
twitteria_mate/src/com/insideria/twitteria/maps/MainEventMap.mxml
#18-21 (formatted)
<EventHandlers
type="{TimelineReceivedEvent.TIMELINE_RECEIVED}"
debug="true">
<MethodInvoker
generator="{TwitterManager}"
method="setCurrentTweets"
arguments="{[event.tweets]}" />
<EventAnnouncer
generator="{ViewStateEvent}"
type="{ViewStateEvent.SHOW_MAIN_VIEW}"
bubbles="true" />
</EventHandlers>
When it gets it, it invokes setCurrentTweets on a generated TwitterManager and passes the tweets we set on the event. It then uses an EventAnnouncer to fire a ViewStateEvent of type ViewStateEvent.SHOW_MAIN_VIEW. Let’s take those one at a time.
The TwitterManager is our model-type object, following what I take to be a Mate naming convention. It’s simple enough.
twitteria_mate/src/com/insideria/twitteria/business/TwitterManager.as
#5-12 (formatted)
public class TwitterManager {
[Bindable]
public var currentTweets:ArrayCollection;
public function setCurrentTweets(tweets:Array):void {
currentTweets = new ArrayCollection(tweets);
}
It just has a Bindable collection of tweets and a way to set them. Now that they’re set, how do they get to the view? A PropertyInjector, with the help of Flex binding.
twitteria_mate/src/com/insideria/twitteria/maps/MainEventMap.mxml
#31-33 (formatted)
<Injectors target="{MainView}">
<PropertyInjector
source="{TwitterManager}"
sourceKey="currentTweets"
targetKey="currentTweets" />
</Injectors>
This is another very Mate way of doing things. This is saying that Mate should bind the currentTweets property of any cached TwitterManager into the cached MainView instance’s currentTweets. Hold on, when did a MainView get cached? Well, as a service to the user, Mate listens for the event from any view (I believe the creationComplete event) just like it does for any other user defined bubbling event, and then caches a reference to that view. That way the EventMap has a way to communicate with the view of any type. Sneaky, eh? I thought so. Now whenever the currentTweets on our manager changes, that view will be updated. Now we have the data getting to the right view, but how do we get the ViewStack on the application onto the right index?
That second tag, the EventAnnouncer fires off a ViewStateEvent.
twitteria_mate/src/com/insideria/twitteria/events/ViewStateEvent.as
#7-11 (formatted)
public static const SHOW_MAIN_VIEW:String = "showMainView";
public function ViewStateEvent(
type:String,
bubbles:Boolean=true,
cancelable:Boolean=false) {
super(type, bubbles, cancelable);
}
Since we’re using the EventAnnouncer to fire this off, it needs the standard event constructor. Also, we could have lots of view state constants to use for different view state events since Flash events are unique by sort of a weird mix of class and type property. So where does this event go? Well, if we look back on the application, we’ll see.
twitteria_mate/src/twitteria_mate.mxml #23 (formatted)
<mate:Listener
type="{ViewStateEvent.SHOW_MAIN_VIEW}"
method="showMainView" />
Here’s a Listener tag that listens for just that event type. When it gets it, it calls showMainView.
twitteria_mate/src/twitteria_mate.mxml #7-12
public const LOGIN_VIEW:int = 0;
public const MAIN_VIEW:int = 1;
private function showMainView(e:Event):void {
mainViewStack.selectedIndex = MAIN_VIEW;
}
That method sets the view stack to where it should be. Now we have the MainView showing in the ViewStack and right data in the list in MainView. Let’s have a look at setting status now.
Setting Status
As you probably can guess, we set status by firing off an event. Here’s where we do it:
twitteria_mate/src/com/insideria/twitteria/view/MainView.mxml
#12-16
private function setStatus():void {
var e:SetStatusEvent = new SetStatusEvent(statusText.text);
dispatchEvent(e);
statusText.clear();
}
And here’s where it ends up:
twitteria_mate/src/com/insideria/twitteria/maps/MainEventMap.mxml
#23-25 (formatted)
<EventHandlers type="{SetStatusEvent.SET_STATUS}" debug="true">
<MethodInvoker
generator="{TwitterDelegate}"
method="setStatus"
arguments="{[event.statusText]}" />
</EventHandlers>
We call setStatus on the cached TwitterDelegate, passing in the statusText from the incoming event.
twitteria_mate/src/com/insideria/twitteria/business/TwitterDelegate.as
#58-61
private function statusSet(te:TwitterEvent):void {
var e:StatusSetEvent = new StatusSetEvent();
dispatcher.dispatchEvent(e);
}
When the delegate is done, it dispatches a StatusSetEvent through its dispatcher.
twitteria_mate/src/com/insideria/twitteria/maps/MainEventMap.mxml
#27-29 (formatted)
<EventHandlers type="{StatusSetEvent.STATUS_SET}" debug="true">
<MethodInvoker
generator="{TwitterDelegate}"
method="loadTimeline" />
</EventHandlers>
Back in the EventMap, it catches that event and reloads by calling back to the delegate, which kicks off that whole chain again.
Next Up
Mate’s sort of a different beast from the other frameworks. The EventMap approach is novel, as is the class caching. Once you see how it works, it’s a lot of fun to use, though.
Now we’ve built our application using four different Flex frameworks. Again, although it wasn’t an exhaustive look at each framework or its capabilities, and since our use cases may have been a little out of the ordinary especially around the delegate area, I hope that this has at least shown you how it feels to use these frameworks in a day-to-day setting.
Next up, we’re going to get into the opinion section of the app,
where I tell you how I think each framework stacks up against the others, which
one I’d like to use from now on, and which one I think renders the most
Programmer Joy.
Read the rest of FrameworkQuest 2008:
- Part 1 - Introduction
- Part 2 - Get Control with Cairngorm
- Part 3 - Framework Agnostic Views with PureMVC
- Part 4 - loC with Swiz
- Part 5 - Mate, the Pure MXML Framework
- Part 6 - The Exciting Conclusion
RIA Conference
Attention InsideRIA readers: Check out the InsideRIA training and networking event in San Jose, August 23-24. We’d love to see you there!





Facebook Application Development
We have used mate on three major projects now (one enterprise as a replacement to cairngorm) and I couldn't be happier with the approach the asfusion folks have taken with it.
This framework is great.
Seems like more work/boilerplate than I thought this was going to be...
This has been by far the best series of articles outside Adobe literature I've read on Flex thus far!! I don't know how you found the time to learn the frameworks (knowing only PureMVC myself but having a vague familiarity with the rest), write and revise your app, and describe it all so eloquently over and over but it's greatly appreciated. It helped my decision between Swiz and Mate but I still look forward to your conclusion … now if only there were something like this between Scala and Clojure and Ruby and Python (looking to change server-side languages) ;)
@Jon - good to hear. Can you tell us which one you chose and why? Also, (shameless plug) pick up this book and go with Rails on the server side: http://www.amazon.com/Flex-Rails-Building-Internet-Applications/dp/0321543378
:)
@Jon,
I'd also be interested to know about your selection. I'm currently looking into a new framework and appear to have it narrowed down to Mate or Swiz.
@Tony,
Just wanted to post and say thanks for posting these articles on the various framerworks. Interesting, educational, balanced...3 things that are not an easy thing to accomplish together.
Thanks, I think Tony will have a better perspective from his experience at EffectiveUI (I enjoyed your Flex on Rails presentation on AMP btw, and additionally recommend the ones on Cairngorn, Swiz, and Mate), his history using Cairngorm, and his parallel implementations of this application, but here's my takeaway:
Cairngorm
Pros: Adobe sourced [and officially supported?], code generation tools, very popular [and most jobs?].
Cons: Having started out with PureMVC (my first MVC in any language), Cairngorm looks like all the boilerplate sans any of the purity (and imho, the aesthetic) of what Tony aptly called framework agnosticism …
PureMVC
Pros: Framework footprint on Flex views confined (both by enforcement and best practice) to top level creationComplete event[s], also very popular.
Cons: Again, boilerplate (Fabrication helps, but seriously how many SWCs does it take to change a light bulb?), data binding to Flex views requires additional footwork (for better and worse).
Swiz
Pros: Lightweight (and smallest binary except for PureMVC, but Fabrication bumps that up significantly), extremely succinct, clean data binding to Flex views.
Cons: String literals in lieu of constants in metadata annotations (historical AS3 language limitation), mitigating framework dependencies from Flex views might require diligence, least documentation, least popular [and least vetted?].
Mate
Pros: The event bus sounds like the most intuitive communication solution, flexible design patterns, mostly bindable IOC containers (unlike Swiz).
Cons: Like ColdFusion, looks like tag soup to me (entirely subjectively seems like a declarative format poorly represents concepts being mapped).
Verdict:
Cairngorm looks messy.
PureMVC feels bulky.
Mate looks like CF.
Swiz because my primary [and reactionary] criteria was conciseness.
Cool I replied but waiting for moderation because of some links I included to resources I found helpful :)
Thanks.
Really nice overview that helps to quickly understand certain concepts :)
And use less captchas, man ))) I should have to fill out 2 of them in order to post this comment ))
Very nice read!
Very nice read!