<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" 
      xmlns:thr="http://purl.org/syndication/thread/1.0">
  <link rel="alternate" type="text/html" href="http://www.insideria.com/2008/12/frameworkquest-2008-part-5-mat.html" />
  <link rel="self" type="application/atom+xml" href="http://www.insideria.com/atom.xml" />
  <id>tag:www.insideria.com,2009://34/tag:www.insideria.com,2008://34.33985-</id>
  <updated>2009-11-16T15:19:48Z</updated>
  <title>Comments for FrameworkQuest 2008 Part 5: Mate, the Pure MXML Framework (http://www.insideria.com/2008/12/frameworkquest-2008-part-5-mat.html)</title>
  <generator uri="http://www.sixapart.com/movabletype/">Movable Type 4.21-en</generator>
  <entry>
    <id>tag:www.insideria.com,2008://34.33985</id>
    <link rel="alternate" type="text/html" href="http://www.insideria.com/2008/12/frameworkquest-2008-part-5-mat.html" />
    <link rel="service.edit" type="application/atom+xml" href="http://blogs.oreilly.com/cgi-bin/mt/mt-atom.cgi/weblog/blog_id=34/entry_id=33985" title="FrameworkQuest 2008 Part 5: Mate, the Pure MXML Framework" />
    <published>2008-12-30T13:00:24Z</published>
    <updated>2009-03-13T14:58:40Z</updated>
    <title>FrameworkQuest 2008 Part 5: Mate, the Pure MXML Framework</title>
    <summary>Let&#8217;s get this out of the way first thing. It&#8217;s Mah-tay, not M-eight. Like the drink, the creators of Mate, Nahuel Faronda and Laura Arguello, come from Argentina. If you&#8217;ve never tried Mate (the drink), you should - it&#8217;s tasty....</summary>
    <author>
      <name>Tony Hillerson</name>
      
    </author>
    
    <category term="Adobe Feed" />
    
    <category term="Features" />
    
    <content type="html" xml:lang="en" xml:base="http://www.insideria.com/">
      <![CDATA[<p>Let&#8217;s get this out of the way first thing. It&#8217;s Mah-tay, not
M-eight. Like <a href="http://en.wikipedia.org/wiki/Mate_(beverage)"><span
style='color:#000099'>the drink</span></a>, the creators of <a
href="http://mate.asfusion.com"><span style='color:#000099'>Mate</span></a>, <a
href="http://www.asfusion.com/"><span style='color:#000099'>Nahuel Faronda and
Laura Arguello</span></a>, come from Argentina. If you&#8217;ve never tried Mate (the
drink), you should - it&#8217;s tasty. If you&#8217;ve never tried <a
href="http://mate-framework.googlecode.com/"><span style='color:#000099'>Mate</span></a>
(the framework), well, that&#8217;s tasty, too, and you&#8217;re about to dig into a big
bowl full. Sorry about that mixed metaphor there.</p>



<p>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&#8217;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.</p>



<p>Since it&#8217;s very unobtrusively event based (you&#8217;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&#8217;ll be surprised at how much you can do right in MXML.</p>



<p>Let&#8217;s look at one of those green box things again. The <span
class=Code><span style='font-family:Monaco'>Delegate</span></span> is yellow to
show that it&#8217;s optional.</p>



<p><img width=468 height=128 src="http://www.insideria.com/upload/2008/11/image002.jpg"
v:shapes="_x0000_s1026"></p>



<p>So when a user interacts with the view, and event is fired. The <span
class=Code><span style='font-family:Monaco'>EventMap</span></span>, declared on
the root application receives all events dispatched anywhere in the view as
long as the <span class=Code><span style='font-family:Monaco'>bubbles</span></span>
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 <span class=Code><span
style='font-family:Monaco'>bubbles</span></span> property set to true. This is
how Mate is so unobtrusive. You don&#8217;t have to define event listeners all over
the place, just define some code in the <span class=Code><span
style='font-family:Monaco'>EventMap</span></span> to catch certain types of
events. The <span class=Code><span style='font-family:Monaco'>EventMap</span></span>
takes care of calling the service in simple situations, but it could delegate
the service call to a delegate as well.</p>



<p>The <span class=Code><span style='font-family:Monaco'>EventMap</span></span>
could also <a
href="http://mate.asfusion.com/page/documentation/tags/commandinvoker"><span
style='color:#000099'>fire off a command</span></a>, 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&#8217;s
documentation is particularly good and easy to use compared to the other
frameworks, so <a href="http://mate.asfusion.com/page/documentation/"><span
style='color:#000099'>have a look at it</span></a> if you want.</p>



<p>To get data into the view, Mate either defines an IoC style <span
class=Code><span style='font-family:Monaco'>Injector</span></span> or simply
dispatches an event with an <span class=Code><span style='font-family:Monaco'>EventAnnouncer</span></span>
and the view can use Mate&#8217;s <span class=Code><span style='font-family:Monaco'>Listener</span></span>
tag to be notified of these events. We&#8217;ll see both ways of doing things.
Storing data in the model is delegated to objects that most of the examples
call <span class=Code><span style='font-family:Monaco'>Managers</span></span>.
Some examples use a <span class=Code><span style='font-family:Monaco'>Manager</span></span>
to actually do service interaction. Again that&#8217;s up to you and how pure you
want the model to be.</p>



<p>Ok, let&#8217;s start looking into how I did this application the Mate
way.</p>



<p class=Sub-heading>Twitter Through A Bomba</p>

<p>The first Mate specific code in our app is on the root
application.</p>



<p><b>twitteria_mate/src/twitteria_mate.mxml #21<o:p></o:p></b></p>

<div class="acode" style="overflow: auto; padding: 10px;" ><div style="overflow-x: visible;">
<code language="perl">
<pre>
&lt;maps:MainEventMap /&gt;</pre>
</code>

</div></div> 


<p>The <a
href="http://mate.asfusion.com/page/documentation/tags/eventmap"><span
class=Code><span style='font-family:Monaco;color:#000099'><u>EventMap</u></span></span></a>
is central to any Mate application, so it&#8217;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.</p>



<p>Each application defines its own <span class=Code><span
style='font-family:Monaco'>EventMap</span></span>, and ours is imaginatively
called <span class=Code><span style='font-family:Monaco'>MainEventMap</span></span>.
There&#8217;s not a lot more to see on the application, so let&#8217;s look at logging in.</p>



<p class=Sub-heading>Logging In</p>

<p>Once again, hitting enter in the password field kicks off the
login process. It calls the <span class=Code><span style='font-family:Monaco'>login</span></span>
method on <span class=Code><span style='font-family:Monaco'>LoginView</span></span>.</p>



<p><b>twitteria_mate/src/com/insideria/twitteria/view/LoginView.mxml
#10-13 (formatted)<o:p></o:p></b></p>

<div class="acode" style="overflow: auto; padding: 10px;" ><div style="overflow-x: visible;">
<code language="perl">
<pre>
<span class="category1">public</span> <span class="category1">function</span> login():<span class="category1">void</span> {
      <span class="category1">var</span> <span class="category1">le</span>:LoginEvent = <span class="category1">new</span> LoginEvent(
           usernameText.<span class="category2">text</span>, passwordText.<span class="category2">text</span>
      ); 
      dispatchEvent(<span class="category1">le</span>);
}</pre>
</code>

</div></div> 

<p>We dispatch a <span class=Code><span style='font-family:Monaco'>LoginEvent</span></span>
and send along the username and password. Nothing framework specific. Let&#8217;s
look at the <span class=Code><span style='font-family:Monaco'>LoginEvent</span></span>.</p>



<p><b>twitteria_mate/src/com/insideria/twitteria/events/LoginEvent.as
#7-16 (formatted)<o:p></o:p></b></p>

<div class="acode" style="overflow: auto; padding: 10px;" ><div style="overflow-x: visible;">
<code language="perl">
<pre>
<span class="category1">public</span> <span class="category1">static</span> const LOG_IN:<span class="category2">String</span> = "<span class="quote">login</span>";

<span class="category1">public</span> <span class="category1">var</span> username:<span class="category2">String</span>;
<span class="category1">public</span> <span class="category1">var</span> <span class="category2">password</span>:<span class="category2">String</span>;

<span class="category1">public</span> <span class="category1">function</span> LoginEvent(username:<span class="category2">String</span>, <span class="category2">password</span>:<span class="category2">String</span>) {
      <span class="category1">super</span>(LOG_IN, <span class="category1">true</span>, <span class="category1">false</span>);
      <span class="category1">this</span>.username = username;
      <span class="category1">this</span>.<span class="category2">password</span> = <span class="category2">password</span>;
}</pre>
</code>

</div></div> 




<p>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 <span class=Code><span
style='font-family:Monaco'>username</span></span> and <span class=Code><span
style='font-family:Monaco'>password</span></span> payload. The <span
class=Code><span style='font-family:Monaco'>super</span></span> call is
important. The arguments are &#8216;type&#8217;, &#8216;bubbles&#8217;, and &#8216;cancelable&#8217;. The type is
our constant, and bubbles is set to true. That&#8217;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 <span class=Code><span
style='font-family:Monaco'>EventMap</span></span> ultimately listens for this
event.</p>



<p><b>twitteria_mate/src/com/insideria/twitteria/maps/MainEventMap.mxml
#13-16 (formatted)<o:p></o:p></b></p>

<div class="acode" style="overflow: auto; padding: 10px;" ><div style="overflow-x: visible;">
<code language="perl">
<pre>
&lt;EventHandlers <span class="category2">type</span>="<span class="quote">{LoginEvent.LOG_IN}</span>" debug="<span class="quote">true</span>"&gt;
     &lt;ObjectBuilder
          generator="<span class="quote">{TwitterDelegate}</span>"
          constructorArguments="<span class="quote">{[
               event.username, event.password, scope.dispatcher
          ]}</span>" /&gt;
     &lt;MethodInvoker
          generator="<span class="quote">{TwitterDelegate}</span>"
          <span class="category1">method</span>="<span class="quote">loadTimeline</span>" /&gt;
&lt;/EventHandlers&gt;</pre>
</code>

</div></div> 

<p>Wow. There&#8217;s a lot going on here, so let&#8217;s break it down. The <span
class=Code><span style='font-family:Monaco'>EventHandlers</span></span> tag
defines the actions to take for a certain type of event, designated in the <span
class=Code><span style='font-family:Monaco'>type</span></span> property. This
corresponds to the constant in our <span class=Code><span style='font-family:
Monaco'>LoginEvent</span></span>, so this is the event handler for when that
event bubbles up.</p>



<p>When that event gets caught, the first tag takes over. The <a
href="http://mate.asfusion.com/page/documentation/tags/objectbuilder"><span
class=Code><span style='font-family:Monaco;color:#000099'>ObjectBuilder</span></span></a>
tag creates an object of a certain type, which is set in the <span class=Code><span
style='font-family:Monaco'>generator</span></span> 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.</p>



<p>The <span style='font-size:11.0pt;font-family:Monaco'>constructorArguments</span>
are, of course, how you pass in arguments to the class&#8217; constructor. Here we
pass in, from the incoming event, the username, password, and from the <span
class=Code><span style='font-family:Monaco'>scope</span></span> property of the
<span class=Code><span style='font-family:Monaco'>EventMap</span></span>, a <span
class=Code><span style='font-family:Monaco'>dispatcher</span></span>. Hopefully
the event properties are clear enough to you. The dispatcher thing needs to be
cleared up a bit though, I bet. What we&#8217;re going to do, since we don&#8217;t have a
standard service to call, like a <span class=Code><span style='font-family:
Monaco'>RemoteObject</span></span>, <span class=Code><span style='font-family:
Monaco'>WebService</span></span>, or <span class=Code><span style='font-family:
Monaco'>HTTPService</span></span>, which all have <a
href="http://mate.asfusion.com/page/documentation/tags/services"><span
style='color:#000099'>invokers</span></a> in Mate, is to have a delegate that
dispatches events when things happen. To make that work with any Mate <span
class=Code><span style='font-family:Monaco'>Listeners</span></span>, which
we&#8217;ll see in a bit, we need to dispatch the events through Mate. This <span
class=Code><span style='font-family:Monaco'>dispatcher</span></span> passed
into the <span class=Code><span style='font-family:Monaco'>TwitterDelegate&#8217;s</span></span>
constructor lets us do that.</p>



<p>Next, we use a <a
href="http://mate.asfusion.com/page/documentation/tags/methodinvoker"><span
class=Code><span style='font-family:Monaco;color:#000099'><u>MethodInvoker</u></span></span></a>
tag to invoke a method on the <span class=Code><span style='font-family:Monaco'>TwitterDelegate</span></span>,
namely <span class=Code><span style='font-family:Monaco'>loadTimeline</span></span>.
The <span class=Code><span style='font-family:Monaco'>MethodInvoker</span></span>
uses the same generator style. Since the defaults are in place on the <span
class=Code><span style='font-family:Monaco'>ObjectBuilder</span></span>, the
object that was built there will be reused here. In fact, We didn&#8217;t even really
need to use the <span class=Code><span style='font-family:Monaco'>ObjectBuilder</span></span>,
because the generator in <span class=Code><span style='font-family:Monaco'>MethodInvoker</span></span>
would have cached the class too. That&#8217;s the default behavior of most of the
tags used in the <span class=Code><span style='font-family:Monaco'>EventMap</span></span>.
Why did I use the <span class=Code><span style='font-family:Monaco'>ObjectBuilder</span></span>
then? Just to show it could be done and to make it explicit. Look, I&#8217;m trying
to teach here.</p>



<p>That was a lot of explanation for two or three tags, so let&#8217;s say
it in plain English. When the <span class=Code><span style='font-family:Monaco'>EventMap</span></span>
gets the <span class=Code><span style='font-family:Monaco'>LoginEvent</span></span>,
it builds a <span class=Code><span style='font-family:Monaco'>TwitterDelegate</span></span>
and caches the instance for whenever another <span class=Code><span
style='font-family:Monaco'>TwitterDelegate</span></span> is requested. Then we
invoke <span class=Code><span style='font-family:Monaco'>loadTimeline</span></span>
on a <span class=Code><span style='font-family:Monaco'>TwitterDelegate</span></span>,
which uses the cached instance. Let&#8217;s see what happens in the delegate.</p>



<p class=Sub-heading>Loading The Timeline</p>

<p>Just like before, we decide on using the <span class=Code><span
style='font-family:Monaco'>dummyData</span></span> or not, and possibly call
the Twitter service.</p>



<p><b>twitteria_mate/src/com/insideria/twitteria/business/TwitterDelegate.as
#33-42 (formatted)<o:p></o:p></b></p>

<div class="acode" style="overflow: auto; padding: 10px;" ><div style="overflow-x: visible;">
<code language="perl">
<pre>
<span class="category1">public</span> <span class="category1">function</span> loadTimeline():<span class="category1">void</span> {
      <span class="category1">if</span> (useDummyData) {
            <span class="category1">var</span> te:TwitterEvent = <span class="category1">new</span> TwitterEvent(
                 TwitterEvent.ON_FRIENDS_TIMELINE_RESULT
            );
            te.<span class="category2">data</span> = getDummyData();
            friendsTimelineLoaded(te);
       } <span class="category1">else</span> {
            twitterService.loadFriendsTimeline(username);
       }
}</pre>
</code>

</div></div> 

<p>And either way, the callback is executed.</p>

<p><b>twitteria_mate/src/com/insideria/twitteria/business/TwitterDelegate.as
#53-56 (formatted)<o:p></o:p></b></p>

<div class="acode" style="overflow: auto; padding: 10px;" ><div style="overflow-x: visible;">
<code language="perl">
<pre>
<span class="category1">private</span> <span class="category1">function</span> friendsTimelineLoaded(te:TwitterEvent):<span class="category1">void</span> {
      <span class="category1">var</span> e:TimelineReceivedEvent = 
           <span class="category1">new</span> TimelineReceivedEvent(te.<span class="category2">data</span> as <span class="category2">Array</span>);
      dispatcher.dispatchEvent(e);
}</pre>
</code>

</div></div> 

<p>This time it&#8217;s different, though, and we get together a <span
class=Code><span style='font-family:Monaco'>TimelineReceivedEvent</span></span>
with the array of tweets and dispatch it through the dispatcher we got from the
<span class=Code><span style='font-family:Monaco'>MainEventMap</span></span>
when the delegate was constructed.</p>


<p>The <span class=Code><span style='font-family:Monaco'>MainEventMap</span></span>
is listening for that kind of event:</p>



<p><b>twitteria_mate/src/com/insideria/twitteria/maps/MainEventMap.mxml
#18-21 (formatted)<o:p></o:p></b></p>

<div class="acode" style="overflow: auto; padding: 10px;" ><div style="overflow-x: visible;">
<code language="perl">
<pre>
&lt;EventHandlers 
     <span class="category2">type</span>="<span class="quote">{TimelineReceivedEvent.TIMELINE_RECEIVED}</span>"
     debug="<span class="quote">true</span>"&gt;
     &lt;MethodInvoker
          generator="<span class="quote">{TwitterManager}</span>"
          <span class="category1">method</span>="<span class="quote">setCurrentTweets</span>"
          <span class="category2">arguments</span>="<span class="quote">{[event.tweets]}</span>" /&gt;
     &lt;EventAnnouncer
          generator="<span class="quote">{ViewStateEvent}</span>" 
          <span class="category2">type</span>="<span class="quote">{ViewStateEvent.SHOW_MAIN_VIEW}</span>"
          bubbles="<span class="quote">true</span>" /&gt;
&lt;/EventHandlers&gt;</pre>
</code>

</div></div> 
<p>When it gets it, it invokes <span class=Code><span
style='font-family:Monaco'>setCurrentTweets</span></span> on a generated <span
class=Code><span style='font-family:Monaco'>TwitterManager</span></span> and
passes the tweets we set on the event. It then uses an <a
href="http://mate.asfusion.com/page/documentation/tags/eventannouncer"><span
class=Code><span style='font-family:Monaco;color:#000099'><u>EventAnnouncer</u></span></span></a>
to fire a <span class=Code><span style='font-family:Monaco'>ViewStateEvent</span></span>
of type <span class=Code><span style='font-family:Monaco'>ViewStateEvent.SHOW_MAIN_VIEW</span></span>.
Let&#8217;s take those one at a time.</p>



<p>The <span class=Code><span style='font-family:Monaco'>TwitterManager</span></span>
is our model-type object, following what I take to be a Mate naming convention.
It&#8217;s simple enough.</p>





<p><b>twitteria_mate/src/com/insideria/twitteria/business/TwitterManager.as
#5-12 (formatted)<o:p></o:p></b></p>

<div class="acode" style="overflow: auto; padding: 10px;" ><div style="overflow-x: visible;">
<code language="perl">
<pre>
<span class="category1">public</span> <span class="category1">class</span> TwitterManager {
      [Bindable]
      <span class="category1">public</span> <span class="category1">var</span> currentTweets:ArrayCollection;
     
      <span class="category1">public</span> <span class="category1">function</span> setCurrentTweets(tweets:<span class="category2">Array</span>):<span class="category1">void</span> {
            currentTweets = <span class="category1">new</span> ArrayCollection(tweets);
       }</pre>
</code>

</div></div> 


<p>It just has a <span style='font-size:11.0pt;font-family:Monaco;
color:#0033FF'>Bindable</span> collection of tweets and a way to set them. Now
that they&#8217;re set, how do they get to the view? A <a
href="http://mate.asfusion.com/page/documentation/tags/propertyinjector"><span
style='color:#000099'>PropertyInjector</span></a>, with the help of Flex
binding.</p>



<p><b>twitteria_mate/src/com/insideria/twitteria/maps/MainEventMap.mxml
#31-33 (formatted)<o:p></o:p></b></p>

<div class="acode" style="overflow: auto; padding: 10px;" ><div style="overflow-x: visible;">
<code language="perl">
<pre>
&lt;Injectors <span class="category2">target</span>="<span class="quote">{MainView}</span>"&gt;
     &lt;PropertyInjector
          source="<span class="quote">{TwitterManager}</span>"
          sourceKey="<span class="quote">currentTweets</span>"
          targetKey="<span class="quote">currentTweets</span>" /&gt;
&lt;/Injectors&gt;</pre>
</code>

</div></div> 


<p>This is another very Mate way of doing things. This is saying
that Mate should bind the <span class=Code><span style='font-family:Monaco'>currentTweets</span></span>
property of any cached <span class=Code><span style='font-family:Monaco'>TwitterManager</span></span>
into the cached <span class=Code><span style='font-family:Monaco'>MainView</span></span>
instance&#8217;s <span class=Code><span style='font-family:Monaco'>currentTweets</span></span>.
Hold on, when did a <span class=Code><span style='font-family:Monaco'>MainView</span></span>
get cached? Well, as a service to the user, Mate listens for the event from any
view (I believe the <span class=Code><span style='font-family:Monaco'>creationComplete</span></span>
event) just like it does for any other user defined bubbling event, and then
caches a reference to that view. That way the <span class=Code><span
style='font-family:Monaco'>EventMap</span></span> has a way to communicate with
the view of any type. Sneaky, eh? I thought so. Now whenever the <span
class=Code><span style='font-family:Monaco'>currentTweets</span></span> 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 <span class=Code><span style='font-family:
Monaco'>ViewStack</span></span> on the application onto the right index?</p>



<p>That second tag, the <span class=Code><span style='font-family:
Monaco'>EventAnnouncer</span></span> fires off a <span class=Code><span
style='font-family:Monaco'>ViewStateEvent</span></span>.</p>





<p><b>twitteria_mate/src/com/insideria/twitteria/events/ViewStateEvent.as
#7-11 (formatted)<o:p></o:p></b></p>

<div class="acode" style="overflow: auto; padding: 10px;" ><div style="overflow-x: visible;">
<code language="perl">
<pre>
<span class="category1">public</span> <span class="category1">static</span> const SHOW_MAIN_VIEW:<span class="category2">String</span> = "<span class="quote">showMainView</span>";

<span class="category1">public</span> <span class="category1">function</span> ViewStateEvent(
                               <span class="category2">type</span>:<span class="category2">String</span>,
                               bubbles:<span class="category2">Boolean</span>=<span class="category1">true</span>,
                               cancelable:<span class="category2">Boolean</span>=<span class="category1">false</span>) {
      <span class="category1">super</span>(<span class="category2">type</span>, bubbles, cancelable);
}</pre>
</code>

</div></div> 


<p>Since we&#8217;re using the <span class=Code><span style='font-family:
Monaco'>EventAnnouncer</span></span> 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&#8217;ll see.</p>

<p class=MsoNormal><span style='font-size:11.0pt;font-family:Monaco;color:blue'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>

<p><b>twitteria_mate/src/twitteria_mate.mxml #23 (formatted)<o:p></o:p></b></p>

<div class="acode" style="overflow: auto; padding: 10px;" ><div style="overflow-x: visible;">
<code language="perl">
<pre>
&lt;mate:Listener
     <span class="category2">type</span>="<span class="quote">{ViewStateEvent.SHOW_MAIN_VIEW}</span>"
     <span class="category1">method</span>="<span class="quote">showMainView</span>" /&gt;</pre>
</code>

</div></div> 

<p>Here&#8217;s a <a
href="http://mate.asfusion.com/page/documentation/tags/listener"><span
class=Code><span style='font-family:Monaco;color:#000099'><u>Listener</u></span></span></a>
tag that listens for just that event type. When it gets it, it calls <span
class=Code><span style='font-family:Monaco'>showMainView</span></span>.</p>



<p><b>twitteria_mate/src/twitteria_mate.mxml #7-12<o:p></o:p></b></p>

<div class="acode" style="overflow: auto; padding: 10px;" ><div style="overflow-x: visible;">
<code language="perl">
<pre>
<span class="category1">public</span> const LOGIN_VIEW:<span class="category1">int</span>    = 0;
<span class="category1">public</span> const MAIN_VIEW:<span class="category1">int</span>     = 1;

<span class="category1">private</span> <span class="category1">function</span> showMainView(e:Event):<span class="category1">void</span> {
      mainViewStack.selectedIndex = MAIN_VIEW;
}</pre>
</code>

</div></div> 


<p>That method sets the view stack to where it should be. Now we
have the <span class=Code><span style='font-family:Monaco'>MainView</span></span>
showing in the <span class=Code><span style='font-family:Monaco'>ViewStack</span></span>
and right data in the list in <span class=Code><span style='font-family:Monaco'>MainView</span></span>.
Let&#8217;s have a look at setting status now.</p>



<p class=Sub-heading>Setting Status</p>

<p>As you probably can guess, we set status by firing off an event.
Here&#8217;s where we do it:</p>



<p><b>twitteria_mate/src/com/insideria/twitteria/view/MainView.mxml
#12-16<o:p></o:p></b></p>

<div class="acode" style="overflow: auto; padding: 10px;" ><div style="overflow-x: visible;">
<code language="perl">
<pre>
<span class="category1">private</span> <span class="category1">function</span> setStatus():<span class="category1">void</span> {
      <span class="category1">var</span> e:SetStatusEvent = <span class="category1">new</span> SetStatusEvent(statusText.<span class="category2">text</span>);
      dispatchEvent(e);
      statusText.<span class="category2">clear</span>();
}</pre>
</code>

</div></div> 


<p>And here&#8217;s where it ends up:</p>



<p><b>twitteria_mate/src/com/insideria/twitteria/maps/MainEventMap.mxml
#23-25 (formatted)<o:p></o:p></b></p>

<div class="acode" style="overflow: auto; padding: 10px;" ><div style="overflow-x: visible;">
<code language="perl">
<pre>
&lt;EventHandlers <span class="category2">type</span>="<span class="quote">{SetStatusEvent.SET_STATUS}</span>" debug="<span class="quote">true</span>"&gt;
     &lt;MethodInvoker
          generator="<span class="quote">{TwitterDelegate}</span>"
          <span class="category1">method</span>="<span class="quote">setStatus</span>"
          <span class="category2">arguments</span>="<span class="quote">{[event.statusText]}</span>" /&gt;
&lt;/EventHandlers&gt;</pre>
</code>

</div></div> 


<p>We call <span class=Code><span style='font-family:Monaco'>setStatus</span></span>
on the cached <span class=Code><span style='font-family:Monaco'>TwitterDelegate</span></span>,
passing in the <span class=Code><span style='font-family:Monaco'>statusText</span></span>
from the incoming event.</p>



<p><b>twitteria_mate/src/com/insideria/twitteria/business/TwitterDelegate.as
#58-61<o:p></o:p></b></p>

<div class="acode" style="overflow: auto; padding: 10px;" ><div style="overflow-x: visible;">
<code language="perl">
<pre>
<span class="category1">private</span> <span class="category1">function</span> statusSet(te:TwitterEvent):<span class="category1">void</span> {
      <span class="category1">var</span> e:StatusSetEvent = <span class="category1">new</span> StatusSetEvent();
      dispatcher.dispatchEvent(e);
}</pre>
</code>

</div></div>


<p>When the delegate is done, it dispatches a StatusSetEvent through
its dispatcher.</p>

<p class=MsoNormal><span style='font-size:11.0pt;font-family:Monaco;color:blue'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>

<p><b>twitteria_mate/src/com/insideria/twitteria/maps/MainEventMap.mxml
#27-29 (formatted)<o:p></o:p></b></p>

<div class="acode" style="overflow: auto; padding: 10px;" ><div style="overflow-x: visible;">
<code language="perl">
<pre>
&lt;EventHandlers <span class="category2">type</span>="<span class="quote">{StatusSetEvent.STATUS_SET}</span>" debug="<span class="quote">true</span>"&gt;
     &lt;MethodInvoker
          generator="<span class="quote">{TwitterDelegate}</span>"
          <span class="category1">method</span>="<span class="quote">loadTimeline</span>" /&gt;
&lt;/EventHandlers&gt;</pre>
</code>

</div></div> 


<p>Back in the <span class=Code><span style='font-family:Monaco'>EventMap</span></span>,
it catches that event and reloads by calling back to the delegate, which kicks
off that whole chain again.</p>



<p class=Sub-heading>Next Up</p>

<p>Mate&#8217;s sort of a different beast from the other frameworks. The <span
class=Code><span style='font-family:Monaco'>EventMap</span></span> approach is
novel, as is the class caching. Once you see how it works, it&#8217;s a lot of fun to
use, though.</p>



<p>Now we&#8217;ve built our application using four different Flex
frameworks. Again, although it wasn&#8217;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. </p>



<p>Next up, we&#8217;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&#8217;d like to use from now on, and which one I think renders the most
Programmer Joy.<span style='font-size:10.0pt;font-family:"Times New Roman";
color:windowtext'><o:p></o:p></span></p>

<p style="padding-top: 15px; border-top: 1px solid #ccc;">Read the rest of FrameworkQuest 2008: 

<ul>

<li><a href="http://www.insideria.com/2008/12/frameworkquest-2008-introducti.html" target="_blank">Part 1 - Introduction</a></li>
<li><a href="http://www.insideria.com/2008/12/frameworkquest-2008-part-2-get.html" target="_blank">Part 2 - Get Control with Cairngorm</a></li>
<li><a href="http://www.insideria.com/2008/12/frameworkquest-2008-part-3-fra.html" target="_blank">Part 3 - Framework Agnostic Views with PureMVC</a></li>
<li><a href="http://www.insideria.com/2008/12/frameworkquest-2008-part-4-ioc.html" target="_blank">Part 4 - loC with Swiz</a></li>
<li>Part 5 - Mate, the Pure MXML Framework</li>
<li><a href="http://www.insideria.com/2009/01/frameworkquest-2008-part-6-the.html" target="_blank">Part 6 - The Exciting Conclusion</a></li>
</ul></p>
<p  style="border-bottom: 1px solid #ccc; padding-top: 15px; margin-bottom: 15px;"></p>
]]>
      
    </content>
  </entry>

  <entry>
    <id>tag:www.insideria.com,2008://34.33985-comment:2049870</id>
    <thr:in-reply-to ref="tag:www.insideria.com,2008://34.33985" type="text/html" href="http://www.insideria.com/2008/12/frameworkquest-2008-part-5-mat.html"/>
    <link rel="alternate" type="text/html" href="http://www.insideria.com/2008/12/frameworkquest-2008-part-5-mat.html#comment-2049870" />
    <title>Comment from Cameron Westland on 2008-12-30</title>
    <author>
        <name>Cameron Westland</name>
        <uri>http://bigbangtechnology.com</uri>
    </author>
    <content type="html" xml:lang="en" xml:base="http://bigbangtechnology.com">
        <![CDATA[<p>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.</p>

<p>This framework is great.</p>]]>
    </content>
    <published>2008-12-30T16:56:51Z</published>
  </entry>

  <entry>
    <id>tag:www.insideria.com,2008://34.33985-comment:2049898</id>
    <thr:in-reply-to ref="tag:www.insideria.com,2008://34.33985" type="text/html" href="http://www.insideria.com/2008/12/frameworkquest-2008-part-5-mat.html"/>
    <link rel="alternate" type="text/html" href="http://www.insideria.com/2008/12/frameworkquest-2008-part-5-mat.html#comment-2049898" />
    <title>Comment from Ansury on 2008-12-30</title>
    <author>
        <name>Ansury</name>
        <uri></uri>
    </author>
    <content type="html" xml:lang="en" xml:base="">
        <![CDATA[<p>Seems like more work/boilerplate than I thought this was going to be...</p>]]>
    </content>
    <published>2008-12-30T21:11:03Z</published>
  </entry>

  <entry>
    <id>tag:www.insideria.com,2008://34.33985-comment:2049921</id>
    <thr:in-reply-to ref="tag:www.insideria.com,2008://34.33985" type="text/html" href="http://www.insideria.com/2008/12/frameworkquest-2008-part-5-mat.html"/>
    <link rel="alternate" type="text/html" href="http://www.insideria.com/2008/12/frameworkquest-2008-part-5-mat.html#comment-2049921" />
    <title>Comment from Jon Toland on 2008-12-30</title>
    <author>
        <name>Jon Toland</name>
        <uri></uri>
    </author>
    <content type="html" xml:lang="en" xml:base="">
        <![CDATA[<p>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 &hellip; now if only there were something like this between Scala and Clojure and Ruby and Python (looking to change server-side languages) ;)</p>]]>
    </content>
    <published>2008-12-31T01:38:15Z</published>
  </entry>

  <entry>
    <id>tag:www.insideria.com,2008://34.33985-comment:2049935</id>
    <thr:in-reply-to ref="tag:www.insideria.com,2008://34.33985" type="text/html" href="http://www.insideria.com/2008/12/frameworkquest-2008-part-5-mat.html"/>
    <link rel="alternate" type="text/html" href="http://www.insideria.com/2008/12/frameworkquest-2008-part-5-mat.html#comment-2049935" />
    <title>Comment from Tony Hillerson on 2008-12-30</title>
    <author>
        <name>Tony Hillerson</name>
        <uri>http://thillerson.blogspot.com</uri>
    </author>
    <content type="html" xml:lang="en" xml:base="http://thillerson.blogspot.com">
        <![CDATA[<p>@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: <a href="http://www.amazon.com/Flex-Rails-Building-Internet-Applications/dp/0321543378">http://www.amazon.com/Flex-Rails-Building-Internet-Applications/dp/0321543378</a></p>

<p>:)</p>]]>
    </content>
    <published>2008-12-31T01:54:30Z</published>
  </entry>

  <entry>
    <id>tag:www.insideria.com,2008://34.33985-comment:2050045</id>
    <thr:in-reply-to ref="tag:www.insideria.com,2008://34.33985" type="text/html" href="http://www.insideria.com/2008/12/frameworkquest-2008-part-5-mat.html"/>
    <link rel="alternate" type="text/html" href="http://www.insideria.com/2008/12/frameworkquest-2008-part-5-mat.html#comment-2050045" />
    <title>Comment from Gareth Arch on 2009-01-01</title>
    <author>
        <name>Gareth Arch</name>
        <uri>http://flexoop.com</uri>
    </author>
    <content type="html" xml:lang="en" xml:base="http://flexoop.com">
        <![CDATA[<p>@Jon,<br />
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.</p>

<p>@Tony,<br />
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.</p>]]>
    </content>
    <published>2009-01-01T15:44:49Z</published>
  </entry>

  <entry>
    <id>tag:www.insideria.com,2008://34.33985-comment:2050078</id>
    <thr:in-reply-to ref="tag:www.insideria.com,2008://34.33985" type="text/html" href="http://www.insideria.com/2008/12/frameworkquest-2008-part-5-mat.html"/>
    <link rel="alternate" type="text/html" href="http://www.insideria.com/2008/12/frameworkquest-2008-part-5-mat.html#comment-2050078" />
    <title>Comment from Jon Toland on 2009-01-02</title>
    <author>
        <name>Jon Toland</name>
        <uri></uri>
    </author>
    <content type="html" xml:lang="en" xml:base="">
        <![CDATA[<p>Thanks, I think Tony will have a better perspective from his experience at EffectiveUI (I enjoyed your <a href="http://www.onflex.org/ted/2008/09/360flex-sj-2008-flex-on-rails-with.php">Flex on Rails</a> presentation on AMP btw, and additionally recommend the ones on <a href="http://onflash.org/ted/2008/10/360flex-sj-2008-cairngorm-for-beginners.php">Cairngorn</a>, <a href="http://www.onflex.org/ted/2008/09/360flex-sj-2008-introduction-to-swiz.php">Swiz</a>, and <a href="http://www.onflex.org/ted/2008/09/360flex-sj-2008-mate-flex-framework-by.php">Mate</a>), his history using Cairngorm, and his <a href="http://gist.github.com/thillerson/twitteria/tree/master">parallel implementations</a> of this application, but here's my takeaway:</p>

<p><strong>Cairngorm</strong><br />
<em>Pros:	</em>Adobe sourced [and officially supported?], code generation tools, very popular [and most jobs?].<br />
<em>Cons:	</em>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 &hellip;</p>

<p><strong>PureMVC</strong><br />
<em>Pros:	</em>Framework footprint on Flex views confined (both by enforcement and best practice) to top level creationComplete event[s], also <a href="http://www.oreillynet.com/pub/pq/196">very popular</a>.<br />
<em>Cons:	</em>Again, boilerplate (<a href="http://www.codedrunks.com/index.php/2008/10/20/slacker-post-fabrication/">Fabrication</a> 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).</p>

<p><strong>Swiz</strong><br />
<em>Pros:	</em>Lightweight (and smallest binary except for PureMVC, but Fabrication bumps that up significantly), extremely succinct, clean data binding to Flex views.<br />
<em>Cons:	</em>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?].</p>

<p><strong>Mate</strong><br />
<em>Pros:	</em>The event bus sounds like the most intuitive communication solution, flexible design patterns, mostly bindable IOC containers (unlike Swiz).<br />
<em>Cons:	</em>Like ColdFusion, looks like tag soup to me (entirely subjectively seems like a declarative format poorly represents concepts being mapped).</p>

<p><strong>Verdict:</strong><br />
Cairngorm looks messy.<br />
PureMVC feels bulky.<br />
Mate looks like CF.<br />
<em>Swiz</em> because my primary [and reactionary] criteria was conciseness.<br />
</p>]]>
    </content>
    <published>2009-01-02T08:18:19Z</published>
  </entry>

  <entry>
    <id>tag:www.insideria.com,2008://34.33985-comment:2050178</id>
    <thr:in-reply-to ref="tag:www.insideria.com,2008://34.33985" type="text/html" href="http://www.insideria.com/2008/12/frameworkquest-2008-part-5-mat.html"/>
    <link rel="alternate" type="text/html" href="http://www.insideria.com/2008/12/frameworkquest-2008-part-5-mat.html#comment-2050178" />
    <title>Comment from Jon Toland on 2009-01-03</title>
    <author>
        <name>Jon Toland</name>
        <uri></uri>
    </author>
    <content type="html" xml:lang="en" xml:base="">
        <![CDATA[<p>Cool I replied but waiting for moderation because of some links I included to resources I found helpful :)</p>]]>
    </content>
    <published>2009-01-03T18:43:58Z</published>
  </entry>

  <entry>
    <id>tag:www.insideria.com,2008://34.33985-comment:2055849</id>
    <thr:in-reply-to ref="tag:www.insideria.com,2008://34.33985" type="text/html" href="http://www.insideria.com/2008/12/frameworkquest-2008-part-5-mat.html"/>
    <link rel="alternate" type="text/html" href="http://www.insideria.com/2008/12/frameworkquest-2008-part-5-mat.html#comment-2055849" />
    <title>Comment from Alexander Arendar on 2009-03-24</title>
    <author>
        <name>Alexander Arendar</name>
        <uri>http://aarendar.wordpress.com</uri>
    </author>
    <content type="html" xml:lang="en" xml:base="http://aarendar.wordpress.com">
        <![CDATA[<p>Thanks.<br />
Really nice overview that helps to quickly understand certain concepts :)<br />
And use less captchas, man ))) I should have to fill out 2 of them in order to post this comment ))</p>]]>
    </content>
    <published>2009-03-24T16:29:05Z</published>
  </entry>

  <entry>
    <id>tag:www.insideria.com,2008://34.33985-comment:2057298</id>
    <thr:in-reply-to ref="tag:www.insideria.com,2008://34.33985" type="text/html" href="http://www.insideria.com/2008/12/frameworkquest-2008-part-5-mat.html"/>
    <link rel="alternate" type="text/html" href="http://www.insideria.com/2008/12/frameworkquest-2008-part-5-mat.html#comment-2057298" />
    <title>Comment from John Gag on 2009-04-09</title>
    <author>
        <name>John Gag</name>
        <uri>http://www.cftips.net</uri>
    </author>
    <content type="html" xml:lang="en" xml:base="http://www.cftips.net">
        <![CDATA[<p>Very nice read! </p>]]>
    </content>
    <published>2009-04-10T04:03:42Z</published>
  </entry>

  <entry>
    <id>tag:www.insideria.com,2008://34.33985-comment:2059620</id>
    <thr:in-reply-to ref="tag:www.insideria.com,2008://34.33985" type="text/html" href="http://www.insideria.com/2008/12/frameworkquest-2008-part-5-mat.html"/>
    <link rel="alternate" type="text/html" href="http://www.insideria.com/2008/12/frameworkquest-2008-part-5-mat.html#comment-2059620" />
    <title>Comment from amber shop on 2009-05-14</title>
    <author>
        <name>amber shop</name>
        <uri>http://www.ambertreasure.co.uk/</uri>
    </author>
    <content type="html" xml:lang="en" xml:base="http://www.ambertreasure.co.uk/">
        <![CDATA[<p>Very nice read! </p>]]>
    </content>
    <published>2009-05-14T15:25:40Z</published>
  </entry>

  <entry>
    <id>tag:www.insideria.com,2008://34.33985-comment:2074150</id>
    <thr:in-reply-to ref="tag:www.insideria.com,2008://34.33985" type="text/html" href="http://www.insideria.com/2008/12/frameworkquest-2008-part-5-mat.html"/>
    <link rel="alternate" type="text/html" href="http://www.insideria.com/2008/12/frameworkquest-2008-part-5-mat.html#comment-2074150" />
    <title>Comment from Ansury on 2009-08-29</title>
    <author>
        <name>Ansury</name>
        <uri></uri>
    </author>
    <content type="html" xml:lang="en" xml:base="">
        <![CDATA[<p>Yes, Jon Toland - Swiz is the winner!  Excellent choice. :)</p>

<p>I think Swiz started with the most open minded approach out of them all, and addresses a new technology (with different strengths, syntaxes, capabilities, and weaknesses than others) from a fresh perspective that other architectures based on previously used solutions (for different technology) don't have.</p>

<p>Emphasizing the always forgotten virtue in IT of *simplicity* and productivity over other priorities produces a more easily maintainable end product than complex, bulky, or "hacky" solutions that sometimes create as much work as they avoid. IMO</p>]]>
    </content>
    <published>2009-08-29T21:06:40Z</published>
  </entry>

  <entry>
    <id>tag:www.insideria.com,2008://34.33985-comment:2138732</id>
    <thr:in-reply-to ref="tag:www.insideria.com,2008://34.33985" type="text/html" href="http://www.insideria.com/2008/12/frameworkquest-2008-part-5-mat.html"/>
    <link rel="alternate" type="text/html" href="http://www.insideria.com/2008/12/frameworkquest-2008-part-5-mat.html#comment-2138732" />
    <title>Comment from Anton on 2009-10-13</title>
    <author>
        <name>Anton</name>
        <uri></uri>
    </author>
    <content type="html" xml:lang="en" xml:base="">
        <![CDATA[<p>@Tony,</p>

<p>So...if I were going to remove the <strong> ObjectBuilder </strong> tag from your code, would the <strong> MethodInvoker </strong> then look like this?</p>



<pre>

<p>     &lt;MethodInvoker<br />
          generator="{TwitterDelegate}"<br />
          constructorArguments="{[<br />
               event.username, event.password, scope.dispatcher<br />
          ]}<br />
          method="loadTimeline"<br />
     /&gt;<br />
</p></pre>

<p><br />
</p>

<p><br />
</p>]]>
    </content>
    <published>2009-10-13T20:43:46Z</published>
  </entry>

</feed
