<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>FlexOut &#187; framework</title>
	<atom:link href="http://flex.exposedout.net/category/flex/flexframework/feed/" rel="self" type="application/rss+xml" />
	<link>http://flex.exposedout.net</link>
	<description>i am an itemrendrer in the making!</description>
	<lastBuildDate>Fri, 13 May 2011 10:05:19 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.1</generator>
		<item>
		<title>FrameworkQuest 2008 Part 6: The Exciting Conclusion</title>
		<link>http://flex.exposedout.net/2009/01/16/frameworkquest-2008-part-6-the-exciting-conclusion/</link>
		<comments>http://flex.exposedout.net/2009/01/16/frameworkquest-2008-part-6-the-exciting-conclusion/#comments</comments>
		<pubDate>Fri, 16 Jan 2009 11:20:19 +0000</pubDate>
		<dc:creator>Vikram singh</dc:creator>
				<category><![CDATA[flex]]></category>
		<category><![CDATA[framework]]></category>

		<guid isPermaLink="false">http://guavus.wordpress.com/?p=171</guid>
		<description><![CDATA[FrameworkQuest Part 6 by Tony Hillerson Find the original post here FrameworkQuest 2008: Introduction FrameworkQuest 2008 Part 2: Get Control with Cairngorm FrameworkQuest 2008 Part 3: Agnostic Views with PureMVC FrameworkQuest 2008 Part 4: IoC With Swiz FrameworkQuest 2008 Part 5: Mate, the Pure MXML Framework FrameworkQuest 2008 Part 6: The Exciting Conclusion print listen [...]


Related posts:<ol><li><a href='http://flex.exposedout.net/2009/01/16/frameworkquest-2008-part-4-ioc-with-swiz/' rel='bookmark' title='Permanent Link: FrameworkQuest 2008 Part 4: IoC With Swiz'>FrameworkQuest 2008 Part 4: IoC With Swiz</a></li>
<li><a href='http://flex.exposedout.net/2009/01/16/frameworkquest-2008-part-5-mate-the-pure-mxml-framework/' rel='bookmark' title='Permanent Link: FrameworkQuest 2008 Part 5: Mate, the Pure MXML Framework'>FrameworkQuest 2008 Part 5: Mate, the Pure MXML Framework</a></li>
<li><a href='http://flex.exposedout.net/2009/01/16/frameworkquest-2008-part-2-get-control-with-cairngorm/' rel='bookmark' title='Permanent Link: FrameworkQuest 2008 Part 2: Get Control with Cairngorm'>FrameworkQuest 2008 Part 2: Get Control with Cairngorm</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>FrameworkQuest Part 6 by <strong>Tony Hillerson</strong><br />
Find the original post <a href="http://www.insideria.com/2009/01/frameworkquest-2008-part-6-the.html?CMP=AFC-ak_article&amp;ATT=FrameworkQuest+2008+Part+6%3A+The+Exciting+Conclusion">here</a></p>
<blockquote><p>
<a href="http://www.insideria.com/2008/12/frameworkquest-2008-introducti.html">FrameworkQuest 2008: Introduction</a><br />
<a href="http://www.insideria.com/2008/12/frameworkquest-2008-part-2-get.html?CMP=AFC-ak_article&amp;ATT=FrameworkQuest+2008++Part+2%3A+Get+Control+with+Cairngorm">FrameworkQuest 2008 Part 2: Get Control with Cairngorm</a><br />
<a href="http://www.insideria.com/2008/12/frameworkquest-2008-part-3-fra.html?CMP=AFC-ak_article&amp;ATT=FrameworkQuest+2008+Part+3%3A+Framework+Agnostic+Views+with+PureMVC">FrameworkQuest 2008 Part 3: Agnostic Views with PureMVC</a><br />
<a href="http://www.insideria.com/2008/12/frameworkquest-2008-part-4-ioc.html?CMP=AFC-ak_article&amp;ATT=FrameworkQuest+2008+Part+4%3A+IoC+With+Swiz">FrameworkQuest 2008 Part 4: IoC With Swiz</a><br />
<a href="http://www.insideria.com/2008/12/frameworkquest-2008-part-5-mat.html?CMP=AFC-ak_article&amp;ATT=FrameworkQuest+2008+Part+5%3A+Mate%2c+the+Pure+MXML+Framework">FrameworkQuest 2008 Part 5: Mate, the Pure MXML Framework</a><br />
<a href="http://www.insideria.com/2009/01/frameworkquest-2008-part-6-the.html?CMP=AFC-ak_article&amp;ATT=FrameworkQuest+2008+Part+6%3A+The+Exciting+Conclusion">FrameworkQuest 2008 Part 6: The Exciting Conclusion</a>
</p></blockquote>
<div class="button"><a href="http://www.insideria.com/print/33986.html" target="_blank">print <img src="http://insideria.com/riaimages/printtag.jpg" style="border:none;" /></a><br />
<a target="_new" href="http://asp2.readspeaker.net/cgi-bin/oreillyrsone?lang=us&amp;voice=Paul&amp;customerid=171&amp;url=http://www.insideria.com/2009/01/frameworkquest-2008-part-6-the.html">listen <img src="http://www.oreillynet.com/images/icon_listen_small.gif" width="10" height="9" alt="Speech Icon" /></a></div>
<p>Well kids, it&#8217;s been a wild ride. We&#8217;ve looked at five<br />
implementations of a simple Twitter client built with no framework, Cairngorm,<br />
PureMVC, Swiz, and Mate. We&#8217;ve talked about important things like pronouncing<br />
the framework&#8217;s names, architectural patterns, Inversion of Control, and<br />
programmer joy.</p>
<p>In this last part, I&#8217;m going to turn off any semblance of<br />
objectivity and let you know what I think about these frameworks. If you&#8217;re not<br />
interested in what I think, I don&#8217;t blame you, but I also don&#8217;t want anyone to<br />
take my word for it and blindly choose which one I like. Take a look at the<br />
examples and see which one you&#8217;d rather work with. Come up with a simple<br />
application and build it four different way. In other words, try before you<br />
buy.</p>
<p>Ok, here we go. First, in prose, and then with some numbers.</p>
<p><strong>Cairngorm</strong></p>
<p>As I mentioned early on, I&#8217;ve been using Cairngorm for a while<br />
now. Does that make me want to stick with it or try something new? Well, I&#8217;ve<br />
liked using Cairngorm. I also like to use <a href="http://www.herrodius.com/blog/"><span>Christophe<br />
Herreman</span></a>&#8216;s<span>&nbsp; </span><a href="http://www.pranaframework.org/"><span>Prana</span></a><br />
to help out a bit with sequences of commands and IoC. In fact, I wanted to have<br />
an article on <a href="http://www.pranaframework.org/"><span>Prana</span></a></p>
<p>in this series, but I just ran out of time. You can settle for this <a href="http://thillerson.blogspot.com/2007/10/delegate-factories-with-prana.html"><span>blog post about delegate factories</span></a>, which shows<br />
how we might have made our dummy data solution a little more palatable.</p>
<p>The thing I like most about Cairngorm is the command pattern. I<br />
really like having commands that are named with a description of what they do,<br />
and I really like that everything to do with getting that specific task done is<br />
inside the command.</p>
<p>Cairngorm, though, being around the longest and the loneliest,<br />
has attracted criticism. It&#8217;s surprising to me, because I think it&#8217;s not a bad<br />
framework, and not even that heavyweight. Even so, I came into this article to<br />
try out these other frameworks and see if one struck me as something I&#8217;d rather<br />
work with from day to day. Let&#8217;s have a look at some criticisms.</p>
<p>Some people don&#8217;t like Cairngorm&#8217;s verbosity when it comes to<br />
defining a new command. I don&#8217;t think there&#8217;s anything wrong there that can&#8217;t<br />
be solved with some <a href="http://www.ericfeminella.com/blog/cairngen/"><span>code generation</span></a>, but I agree that it&#8217;s pretty<br />
verbose.</p>
<p>Other arguments against Cairngorm are usually leveled against its<br />
use of a Singleton model. A Singleton makes unit testing hard, and sometimes<br />
people say it&#8217;s just a glorified &quot;global variable&quot;. Let&#8217;s take these<br />
one at a time.</p>
<p>Singletons are not &quot;global variables&quot;. People make fun<br />
of using global variables because it&#8217;s a rookie way of getting around building<br />
a good architecture. It was the way we built Flash apps before we knew how to<br />
program. That&#8217;s true &#8211; global variables are unsafe because there&#8217;s no guarantee<br />
who&#8217;s accessing and changing them. In short, there&#8217;s no encapsulation. But with<br />
a Singleton, there is encapsulation, because what you&#8217;re dealing with is still<br />
an object. There&#8217;s nothing stopping you from using read-only getters instead of<br />
public properties.</p>
<p>Singletons do, however, make it harder to unit test, because a<br />
simple test that, say, runs a command sequence and tests that a property on the<br />
model changed as expected, changes that model instance of which there is only<br />
one. The more tests, the more the model gets into a strange initial state. I<br />
think that&#8217;s not that big of a deal if you just take the time to reset the<br />
model to a known state before each test. If you have to have a &#8220;logout&#8221; in your<br />
app anyway, you&#8217;ll need to do something like that anyway (unless you cop out<br />
and just refresh the page with javascript). I agree, though, that it&#8217;s extra<br />
code to maintain.</p>
<p>One last problem people have is that Cairngorm has you putting<br />
Cairngorm events on the view. That means you have to make a Cairngorm event,<br />
first, and second it means that you have framework code on the view that makes<br />
it hard to refactor away from Cairngorm.</p>
<p>Now, look. How many times in an app do you just scrap it and<br />
switch frameworks? I never have. I agree that componentizing is great when you<br />
really have a view you can turn into a blackbox component, but if you have a<br />
view specific to a certain app I really don&#8217;t see that it&#8217;s anything but <a href="http://en.wikipedia.org/wiki/Bikeshedding"><span>bikeshedding</span></a><br />
to try to make the view code re-usable. There&#8217;s a point of diminishing returns,<br />
and at that point or even a little before, you should just move on and get the<br />
app done. That&#8217;s why I don&#8217;t care that much about Flex framework code in a Flex<br />
application. I&#8217;m certainly open to the idea of using regular Flash events,<br />
though, so that brings us to PureMVC.</p>
<p><strong>PureMVC</strong></p>
<p>One way I describe the difference between Cairngorm and PureMVC<br />
to people is that Cairngorm doesn&#8217;t have much to say about your view code, and<br />
PureMVC doesn&#8217;t have much to say about your service access code. That&#8217;s why you<br />
see the BusinessDelegate pattern in PureMVC and Cairngorm &#8211; because it works<br />
well. </p>
<p>What PureMVC tries to fix, though, is having the view cluttered<br />
with PureMVC code. It fixes that well &#8211; the only place you have to put PureMVC<br />
code is on the root application. As far as that goes, I like using Flash events<br />
instead of Cairngorm events. What&#8217;s nice there is that if I&#8217;m using a blackbox<br />
component that emits Flash events, I can still easily respond in a Mediator<br />
whereas in Cairngorm I&#8217;d have to catch and re-dispatch an event as a Cairngorm<br />
event if I wanted to take action.</p>
<p>One other important PureMVC goal is to be an Actionscript<br />
framework, not a Flex framework. That means I can&#8217;t (or shouldn&#8217;t) use Flex<br />
binding to wire up a view to a Proxy, I need to have the Mediator do it. Is<br />
that a win? I think binding is great, and I also think it needs special<br />
understanding to use it correctly. In a medium to large sized application, by<br />
using binding right out of the box, you can cause a really huge event storm<br />
whenever any bound property changes and bring performance to a halt. </p>
<p>I think binding is good when used responsibly, so when PureMVC<br />
says to skip it, I&#8217;m interested, but I want to know what it costs to use. So<br />
what I don&#8217;t like about PureMVC is how much boilerplate code there is. I like<br />
the idea of a mediator for views, but there is so much set up to do. The<br />
constants, the <span class="Code"><span>viewComponent</span></span><br />
wrapper, <span class="Code"><span>listNotificationInterests</span></span>,</p>
<p><span class="Code"><span>handleNotification</span></span>,<br />
there&#8217;s a lot of stuff it takes to set up a Mediator. I like PureMVC in<br />
general, but I&#8217;ve never gotten up the energy to use it on a project because of<br />
inertia. It feels like it&#8217;s a big investment to do things the PureMVC way.</p>
<p>Contrast that with the lightest weight framework, Swiz.</p>
<p><strong>Swiz</strong></p>
<p>I have to be honest, when I wrote this article because of the<br />
buzz and <a href="http://www.onflex.org/ted/2008/09/360flex-sj-2008-mate-flex-framework-by.php"><span>Laura&#8217;s presentation at 360 Flex San Jose</span></a>, I<br />
was really prepared to like Mate hands down. (<a href="http://www.onflex.org/ted/2008/09/360flex-sj-2008-introduction-to-swiz.php"><span>BTW, here&#8217;s Chris&#8217;s presentation</span></a>). When I<br />
started using Swiz, though, I immediately felt the joy. You know what I&#8217;m<br />
talking about &#8211; that sense that you&#8217;re in the groove and building something and<br />
there&#8217;s not much work between having an idea and implementing it.</p>
<p>I&#8217;m going to make a distinction that I haven&#8217;t heard before, or<br />
at least don&#8217;t remember hearing. I think there are <a href="http://dictionary.reference.com/browse/proscription"><span>proscriptive</span></a> and <a href="http://dictionary.reference.com/browse/prescription"><span>prescriptive</span></a> tendencies to software<br />
frameworks. On the one hand, proscription means saying what you can&#8217;t do, and<br />
on the other, prescription means saying what you could do. Whereas PureMVC says<br />
a lot of things you shouldn&#8217;t do and some things that you can do, Swiz almost<br />
completely sticks to saying what you can do.</p>
<p>Swiz leaves a lot up to you. All it does is provide some easy<br />
ways to do things like inject a controller or a model into the view and to<br />
easily wire up events with the Mediate metadata tag. From there on out, it&#8217;s up<br />
to you. Swiz is the laissez faire framework, and I really like that.</p>
<p>The only thing is that all the service interaction stuff, the<br />
dynamic delegates and command all expect you to be using RemoteObjects and<br />
delegate methods that return AsyncTokens. I&#8217;m sure this could be fixed, but<br />
unless I&#8217;m missing something until it is fixed Swiz is less useful to anyone<br />
not using AMF services. Since I&#8217;m used to using <a href="http://rubyamf.googlecode.com/"><span>RubyAMF</span></a>,<br />
that&#8217;s great for me, but I can&#8217;t always count on it or BlazeDS or ColdFusion<br />
being on the server side. You can work around it, but it&#8217;d be nice to have<br />
those tools available for other types of services.</p>
<p>One thing I&#8217;d also like to see is an easy way to use the command<br />
pattern where logic is actually written in the commands. I really like that<br />
pattern because I think it&#8217;s cleaner to have logic in commands instead of in<br />
controller files that have to do with more than one type of data or view.<br />
Controllers tend to get a little big, especially with callbacks.</p>
<p>That said, I really like Swiz and I think Autowire and Mediate<br />
are enough incentive to use it over Cairngorm or PureMVC. Swiz is the style of<br />
programming that those three frameworks represent done right. Mate, however, is<br />
a different, hmm&#8230; what should I say&#8230; cup of tea?</p>
<p><strong>Mate</strong></p>
<p>Mate is picking up a lot of steam lately (these puns are going to<br />
keep on coming, people, you may as well just laugh now). Everyone I talk to lately<br />
loves it. I think it&#8217;s a shame that some of those people aren&#8217;t really getting<br />
a chance to try Swiz too, but when you feel what it&#8217;s like developing with<br />
Mate, you&#8217;ll see that it&#8217;s not that big of a shame.</p>
<p>The way I make a distinction between Swiz and Mate is that Swiz<br />
is the Cairngorm style done right, while Mate is a completely different style.<br />
The big difference, I think, is the declarative versus programmatic style of<br />
Mate. Since a lot of what we do in Flex is in MXML, using MXML to set up framework<br />
interaction makes a lot of sense, and also just seems to really fit alongside<br />
the view code.</p>
<p>PureMVC and Mate both want you to use regular old Flash events<br />
instead of framework prescribed events. Swiz wants that too, but sometimes you<br />
need to dispatch through its dispatch system. What makes Mate so elegant,<br />
though, was the insight of just using the event-bubbling to catch them with the<br />
EventMap without defining a bunch of wiring code. Of course, that breaks down<br />
when you want to use a service delegate and have to pass in the dispatcher, but<br />
it doesn&#8217;t break down as hard as Swiz breaks down when you don&#8217;t use<br />
RemoteObjects.</p>
<p>Mate is also really flexible. There are probably more tools there<br />
than you need, and not only that, it has a <a href="http://mate.asfusion.com/page/extensions"><span>plugin<br />
structure</span></a>. I don&#8217;t understand it yet, but that&#8217;s kind of nice. I<br />
also like that Mate has a way of using Commands, although I&#8217;m not sure it would<br />
be worth it to just turn your EventMap into a Cairngorm FrontController.</p>
<p>I like Mate a lot and I can&#8217;t find anything to pick on. Really.<br />
The only thing is I don&#8217;t think I fully understand how it scales, and the way<br />
it does view and object cacheing is a little bit of magic. Magic isn&#8217;t bad, but<br />
again, I just don&#8217;t know what pitfalls await me while using it. I hope to find<br />
out, though, and I&#8217;m really excited to use Mate.</p>
<p><strong>Framework Smackdown</strong></p>
<p>Now is the time when I give you my subjective rating system to<br />
give a bit more quantification. Below is a table rating the frameworks on five<br />
variables from 1-5, 5 being high:</p>
</p>
<p>1.<span>&nbsp;&nbsp;&nbsp; </span><b>Conciseness</b><span> &#8211; How little it takes to get something done in the<br />
framework.</span></p>
</p>
<p>2.<span>&nbsp;&nbsp;&nbsp; </span><b>Familiarity</b><span> &#8211; Once you get past the initial learning phase, how<br />
easy is it to fall into the pattern of using the framework. How easy is it to<br />
think in the framework?</span></p>
</p>
<p>3.<span>&nbsp;&nbsp;&nbsp; </span><b>Flexibility</b><span> &#8211; How easy it is to work with exceptions to normal<br />
development patterns.</span></p>
</p>
<p>4.<span>&nbsp;&nbsp;&nbsp; </span><b>Power</b><span> &#8211; The tools to get the job done</span></p>
</p>
<p>5.<span>&nbsp;&nbsp;&nbsp; </span><b>Programmer<br />
Joy</b><span> &#8211; Is it fun to use the framework? Is<br />
it rewarding, or does it punish you when you have to use it?</span></p>
<table border="0" cellspacing="0" cellpadding="0" bgcolor="white">
<thead>
<tr>
<td width="78" valign="top">
</td>
<td width="80" valign="top">
<p align="center">Conciseness</p>
</td>
<td width="68" valign="top">
<p align="center">Familiarity</p>
</td>
<td width="75" valign="top">
<p align="center">Flexibility</p>
</td>
<td width="58" valign="top">
<p align="center">Power</p>
</td>
<td width="55" valign="top">
<p align="center">Joy</p>
</td>
<td width="52" valign="top">
<p align="center">Total</p>
</td>
</tr>
</thead>
<tr>
<td width="78" valign="top">
<p>Cairngorm</p>
</td>
<td width="80">
<p align="center">2</p>
</td>
<td width="68">
<p align="center">4</p>
</td>
<td width="75">
<p align="center">4</p>
</td>
<td width="58">
<p align="center">3</p>
</td>
<td width="55">
<p align="center">3</p>
</td>
<td width="52">
<p align="center">16</p>
</td>
</tr>
<tr>
<td width="78" valign="top">
<p>PureMVC</p>
</td>
<td width="80">
<p align="center">1</p>
</td>
<td width="68">
<p align="center">2</p>
</td>
<td width="75">
<p align="center">5</p>
</td>
<td width="58">
<p align="center">3</p>
</td>
<td width="55">
<p align="center">1</p>
</td>
<td width="52">
<p align="center">12</p>
</td>
</tr>
<tr>
<td width="78" valign="top">
<p>Swiz</p>
</td>
<td width="80">
<p align="center">5</p>
</td>
<td width="68">
<p align="center">5</p>
</td>
<td width="75">
<p align="center">2</p>
</td>
<td width="58">
<p align="center">2</p>
</td>
<td width="55">
<p align="center">4</p>
</td>
<td width="52">
<p align="center">18</p>
</td>
</tr>
<tr>
<td width="78" valign="top">
<p>Mate</p>
</td>
<td width="80">
<p align="center">4</p>
</td>
<td width="68">
<p align="center">4</p>
</td>
<td width="75">
<p align="center">4</p>
</td>
<td width="58">
<p align="center">5</p>
</td>
<td width="55">
<p align="center">5</p>
</td>
<td width="52">
<p align="center">22</p>
</td>
</tr>
</table>
<p>Well, there you have it, folks. I&#8217;m riding into this one with<br />
flame-proof-pants on, but I hope I&#8217;ve done a little good by giving the<br />
reasoning behind my thinking. I welcome any critique of my reasoning, and if<br />
there&#8217;s a better way to do something in my example code please put comments on<br />
the code in <a href="http://github.com/thillerson/twitteria"><span>Github</span></a> and leave a note here as well. I hope<br />
the example applications help, and I hope that you&#8217;ve all learned a little bit<br />
about yourselves on this journey. Viva Flex.<span></span></p>
<p><a href="http://www.insideria.com/tony-hillerson/">Read more from<br />
Tony Hillerson</a>.</p>


<p>Related posts:<ol><li><a href='http://flex.exposedout.net/2009/01/16/frameworkquest-2008-part-4-ioc-with-swiz/' rel='bookmark' title='Permanent Link: FrameworkQuest 2008 Part 4: IoC With Swiz'>FrameworkQuest 2008 Part 4: IoC With Swiz</a></li>
<li><a href='http://flex.exposedout.net/2009/01/16/frameworkquest-2008-part-5-mate-the-pure-mxml-framework/' rel='bookmark' title='Permanent Link: FrameworkQuest 2008 Part 5: Mate, the Pure MXML Framework'>FrameworkQuest 2008 Part 5: Mate, the Pure MXML Framework</a></li>
<li><a href='http://flex.exposedout.net/2009/01/16/frameworkquest-2008-part-2-get-control-with-cairngorm/' rel='bookmark' title='Permanent Link: FrameworkQuest 2008 Part 2: Get Control with Cairngorm'>FrameworkQuest 2008 Part 2: Get Control with Cairngorm</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://flex.exposedout.net/2009/01/16/frameworkquest-2008-part-6-the-exciting-conclusion/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>FrameworkQuest 2008 Part 5: Mate, the Pure MXML Framework</title>
		<link>http://flex.exposedout.net/2009/01/16/frameworkquest-2008-part-5-mate-the-pure-mxml-framework/</link>
		<comments>http://flex.exposedout.net/2009/01/16/frameworkquest-2008-part-5-mate-the-pure-mxml-framework/#comments</comments>
		<pubDate>Fri, 16 Jan 2009 11:11:24 +0000</pubDate>
		<dc:creator>Vikram singh</dc:creator>
				<category><![CDATA[flex]]></category>
		<category><![CDATA[framework]]></category>

		<guid isPermaLink="false">http://guavus.wordpress.com/?p=169</guid>
		<description><![CDATA[FrameworkQuest Part 5 by Tony Hillerson Find the original post here print listen FrameworkQuest 2008: Introduction FrameworkQuest 2008 Part 2: Get Control with Cairngorm FrameworkQuest 2008 Part 3: Agnostic Views with PureMVC FrameworkQuest 2008 Part 4: IoC With Swiz FrameworkQuest 2008 Part 5: Mate, the Pure MXML Framework FrameworkQuest 2008 Part 6: The Exciting Conclusion [...]


Related posts:<ol><li><a href='http://flex.exposedout.net/2009/01/16/frameworkquest-2008-part-3-framework-agnostic-views-with-puremvc/' rel='bookmark' title='Permanent Link: FrameworkQuest 2008 Part 3: Framework Agnostic Views with PureMVC'>FrameworkQuest 2008 Part 3: Framework Agnostic Views with PureMVC</a></li>
<li><a href='http://flex.exposedout.net/2009/01/16/frameworkquest-2008-part-4-ioc-with-swiz/' rel='bookmark' title='Permanent Link: FrameworkQuest 2008 Part 4: IoC With Swiz'>FrameworkQuest 2008 Part 4: IoC With Swiz</a></li>
<li><a href='http://flex.exposedout.net/2009/01/16/frameworkquest-2008-part-2-get-control-with-cairngorm/' rel='bookmark' title='Permanent Link: FrameworkQuest 2008 Part 2: Get Control with Cairngorm'>FrameworkQuest 2008 Part 2: Get Control with Cairngorm</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>FrameworkQuest Part 5 by <strong>Tony Hillerson</strong><br />
Find the original post <a href="http://www.insideria.com/2008/12/frameworkquest-2008-part-5-mat.html?CMP=AFC-ak_article&amp;ATT=FrameworkQuest+2008+Part+5%3A+Mate%2c+the+Pure+MXML+Framework">here</a></p>
<div class="button"><a href="http://www.insideria.com/print/33985.html" target="_blank">print <img src="http://insideria.com/riaimages/printtag.jpg" style="border:none;" /></a><br />
<a target="_new" href="http://asp2.readspeaker.net/cgi-bin/oreillyrsone?lang=us&amp;voice=Paul&amp;customerid=171&amp;url=http://www.insideria.com/2008/12/frameworkquest-2008-part-5-mat.html">listen <img src="http://www.oreillynet.com/images/icon_listen_small.gif" width="10" height="9" alt="Speech Icon" /></a></div>
<blockquote><p>
<a href="http://www.insideria.com/2008/12/frameworkquest-2008-introducti.html">FrameworkQuest 2008: Introduction</a><br />
<a href="http://www.insideria.com/2008/12/frameworkquest-2008-part-2-get.html?CMP=AFC-ak_article&amp;ATT=FrameworkQuest+2008++Part+2%3A+Get+Control+with+Cairngorm">FrameworkQuest 2008 Part 2: Get Control with Cairngorm</a><br />
<a href="http://www.insideria.com/2008/12/frameworkquest-2008-part-3-fra.html?CMP=AFC-ak_article&amp;ATT=FrameworkQuest+2008+Part+3%3A+Framework+Agnostic+Views+with+PureMVC">FrameworkQuest 2008 Part 3: Agnostic Views with PureMVC</a><br />
<a href="http://www.insideria.com/2008/12/frameworkquest-2008-part-4-ioc.html?CMP=AFC-ak_article&amp;ATT=FrameworkQuest+2008+Part+4%3A+IoC+With+Swiz">FrameworkQuest 2008 Part 4: IoC With Swiz</a><br />
<a href="http://www.insideria.com/2008/12/frameworkquest-2008-part-5-mat.html?CMP=AFC-ak_article&amp;ATT=FrameworkQuest+2008+Part+5%3A+Mate%2c+the+Pure+MXML+Framework">FrameworkQuest 2008 Part 5: Mate, the Pure MXML Framework</a><br />
<a href="http://www.insideria.com/2009/01/frameworkquest-2008-part-6-the.html?CMP=AFC-ak_article&amp;ATT=FrameworkQuest+2008+Part+6%3A+The+Exciting+Conclusion">FrameworkQuest 2008 Part 6: The Exciting Conclusion</a>
</p></blockquote>
<p>Let&#8217;s get this out of the way first thing. It&#8217;s Mah-tay, not<br />
M-eight. Like <a href="http://en.wikipedia.org/wiki/Mate_(beverage)"><span>the drink</span></a>, the creators of <a href="http://mate.asfusion.com"><span>Mate</span></a>, <a href="http://www.asfusion.com/"><span>Nahuel Faronda and<br />
Laura Arguello</span></a>, come from Argentina. If you&#8217;ve never tried Mate (the<br />
drink), you should &#8211; it&#8217;s tasty. If you&#8217;ve never tried <a href="http://mate-framework.googlecode.com/"><span>Mate</span></a></p>
<p>(the framework), well, that&#8217;s tasty, too, and you&#8217;re about to dig into a big<br />
bowl full. Sorry about that mixed metaphor there.</p>
<p>Mate is design to take advantage of MXML and regular old Flash<br />
events dispatched the regular way, not through the framework like Cairngorm or<br />
Swiz (although Swiz is open to regular event dispatching if you set it up<br />
yourself). In that way it&#8217;s like PureMVC. But Mate uses the fact that part of<br />
the framework is defined right at Application level to make the event-driven<br />
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<br />
in a bit) it allows you to make a very componentized application easily, and<br />
although of course you can use the classes from the framework in ActionScript<br />
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>Delegate</span></span> is yellow to<br />
show that it&#8217;s optional.</p>
<p><img /></p>
<p>So when a user interacts with the view, and event is fired. The <span class="Code"><span>EventMap</span></span>, declared on<br />
the root application receives all events dispatched anywhere in the view as<br />
long as the <span class="Code"><span>bubbles</span></span><br />
property of the event is set to true. So the basic way of acting on some user<br />
input is to dispatch a custom event with the <span class="Code"><span>bubbles</span></span> property set to true. This is<br />
how Mate is so unobtrusive. You don&#8217;t have to define event listeners all over<br />
the place, just define some code in the <span class="Code"><span>EventMap</span></span> to catch certain types of<br />
events. The <span class="Code"><span>EventMap</span></span><br />
takes care of calling the service in simple situations, but it could delegate<br />
the service call to a delegate as well.</p>
<p>The <span class="Code"><span>EventMap</span></span><br />
could also <a href="http://mate.asfusion.com/page/documentation/tags/commandinvoker"><span>fire off a command</span></a>, Cairngorm style, if you<br />
like that way of doing things better. Mate is a very flexible framework. In<br />
fact, there are a lot more parts to Mate than are listed here and any of them<br />
could be used to do things a different way or to deal with exceptions. Mate&#8217;s<br />
documentation is particularly good and easy to use compared to the other<br />
frameworks, so <a href="http://mate.asfusion.com/page/documentation/"><span>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>Injector</span></span> or simply<br />
dispatches an event with an <span class="Code"><span>EventAnnouncer</span></span><br />
and the view can use Mate&#8217;s <span class="Code"><span>Listener</span></span><br />
tag to be notified of these events. We&#8217;ll see both ways of doing things.<br />
Storing data in the model is delegated to objects that most of the examples<br />
call <span class="Code"><span>Managers</span></span>.<br />
Some examples use a <span class="Code"><span>Manager</span></span><br />
to actually do service interaction. Again that&#8217;s up to you and how pure you<br />
want the model to be.</p>
<p>Ok, let&#8217;s start looking into how I did this application the Mate<br />
way.</p>
<p class="Sub-heading">Twitter Through A Bomba</p>
<p>The first Mate specific code in our app is on the root<br />
application.</p>
<p><b>twitteria_mate/src/twitteria_mate.mxml #21</b></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
&amp;lt;maps:MainEventMap /&amp;gt;&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>The <a href="http://mate.asfusion.com/page/documentation/tags/eventmap"><span class="Code"><span><u>EventMap</u></span></span></a><br />
is central to any Mate application, so it&#8217;s defined early. Note that although<br />
we only have one, you can have as many as you want, so you can break things up<br />
as clean as you want them.</p>
<p>Each application defines its own <span class="Code"><span>EventMap</span></span>, and ours is imaginatively<br />
called <span class="Code"><span>MainEventMap</span></span>.<br />
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<br />
login process. It calls the <span class="Code"><span>login</span></span><br />
method on <span class="Code"><span>LoginView</span></span>.</p>
<p><b>twitteria_mate/src/com/insideria/twitteria/view/LoginView.mxml<br />
#10-13 (formatted)</b></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
&lt;span class=&quot;category1&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;function&lt;/span&gt; login():&lt;span class=&quot;category1&quot;&gt;void&lt;/span&gt; {<br />
&nbsp; &nbsp; &nbsp; &lt;span class=&quot;category1&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;le&lt;/span&gt;:LoginEvent = &lt;span class=&quot;category1&quot;&gt;new&lt;/span&gt; LoginEvent(<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;usernameText.&lt;span class=&quot;category2&quot;&gt;text&lt;/span&gt;, passwordText.&lt;span class=&quot;category2&quot;&gt;text&lt;/span&gt;<br />
<br />
&nbsp; &nbsp; &nbsp; );<br />
&nbsp; &nbsp; &nbsp; dispatchEvent(&lt;span class=&quot;category1&quot;&gt;le&lt;/span&gt;);<br />
}&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>We dispatch a <span class="Code"><span>LoginEvent</span></span><br />
and send along the username and password. Nothing framework specific. Let&#8217;s<br />
look at the <span class="Code"><span>LoginEvent</span></span>.</p>
<p><b>twitteria_mate/src/com/insideria/twitteria/events/LoginEvent.as<br />
#7-16 (formatted)</b></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
&lt;span class=&quot;category1&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;static&lt;/span&gt; const LOG_IN:&lt;span class=&quot;category2&quot;&gt;String&lt;/span&gt; = &quot;&lt;span class=&quot;quote&quot;&gt;login&lt;/span&gt;&quot;;<br />
<br />
<br />
&lt;span class=&quot;category1&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;var&lt;/span&gt; username:&lt;span class=&quot;category2&quot;&gt;String&lt;/span&gt;;<br />
&lt;span class=&quot;category1&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;category2&quot;&gt;password&lt;/span&gt;:&lt;span class=&quot;category2&quot;&gt;String&lt;/span&gt;;<br />
<br />
&lt;span class=&quot;category1&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;function&lt;/span&gt; LoginEvent(username:&lt;span class=&quot;category2&quot;&gt;String&lt;/span&gt;, &lt;span class=&quot;category2&quot;&gt;password&lt;/span&gt;:&lt;span class=&quot;category2&quot;&gt;String&lt;/span&gt;) {<br />
&nbsp; &nbsp; &nbsp; &lt;span class=&quot;category1&quot;&gt;super&lt;/span&gt;(LOG_IN, &lt;span class=&quot;category1&quot;&gt;true&lt;/span&gt;, &lt;span class=&quot;category1&quot;&gt;false&lt;/span&gt;);<br />
&nbsp; &nbsp; &nbsp; &lt;span class=&quot;category1&quot;&gt;this&lt;/span&gt;.username = username;<br />
&nbsp; &nbsp; &nbsp; &lt;span class=&quot;category1&quot;&gt;this&lt;/span&gt;.&lt;span class=&quot;category2&quot;&gt;password&lt;/span&gt; = &lt;span class=&quot;category2&quot;&gt;password&lt;/span&gt;;<br />
}&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>First, we keep a constant on the event to make sure the type of<br />
the event is clear. We also have a place for the <span class="Code"><span>username</span></span> and <span class="Code"><span>password</span></span> payload. The <span class="Code"><span>super</span></span> call is<br />
important. The arguments are &#8216;type&#8217;, &#8216;bubbles&#8217;, and &#8216;cancelable&#8217;. The type is<br />
our constant, and bubbles is set to true. That&#8217;s important because when an<br />
event bubbles it moves all the way to the top of the display object tree and<br />
anything in the tree can listen for it. The <span class="Code"><span>EventMap</span></span> ultimately listens for this<br />
event.</p>
<p><b>twitteria_mate/src/com/insideria/twitteria/maps/MainEventMap.mxml<br />
#13-16 (formatted)</b></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
&amp;lt;EventHandlers &lt;span class=&quot;category2&quot;&gt;type&lt;/span&gt;=&quot;&lt;span class=&quot;quote&quot;&gt;{LoginEvent.LOG_IN}&lt;/span&gt;&quot; debug=&quot;&lt;span class=&quot;quote&quot;&gt;true&lt;/span&gt;&quot;&amp;gt;<br />
<br />
&nbsp; &nbsp; &nbsp;&amp;lt;ObjectBuilder<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; generator=&quot;&lt;span class=&quot;quote&quot;&gt;{TwitterDelegate}&lt;/span&gt;&quot;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; constructorArguments=&quot;&lt;span class=&quot;quote&quot;&gt;{[<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;event.username, event.password, scope.dispatcher<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ]}&lt;/span&gt;&quot; /&amp;gt;<br />
&nbsp; &nbsp; &nbsp;&amp;lt;MethodInvoker<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; generator=&quot;&lt;span class=&quot;quote&quot;&gt;{TwitterDelegate}&lt;/span&gt;&quot;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;span class=&quot;category1&quot;&gt;method&lt;/span&gt;=&quot;&lt;span class=&quot;quote&quot;&gt;loadTimeline&lt;/span&gt;&quot; /&amp;gt;<br />
&amp;lt;/EventHandlers&amp;gt;&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>Wow. There&#8217;s a lot going on here, so let&#8217;s break it down. The <span class="Code"><span>EventHandlers</span></span> tag<br />
defines the actions to take for a certain type of event, designated in the <span class="Code"><span>type</span></span> property. This<br />
corresponds to the constant in our <span class="Code"><span>LoginEvent</span></span>, so this is the event handler for when that<br />
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>ObjectBuilder</span></span></a><br />
tag creates an object of a certain type, which is set in the <span class="Code"><span>generator</span></span> property. That can be either<br />
a fully qualified path as a string, or a class in a binding, like we have. The<br />
default behavior is to create an object of that type and keep a reference to it<br />
indexed by type. That means that any another object of that type is requested,<br />
the cached object will be returned. This is how Mate deals with the problem<br />
that Cairngorm deals with using singletons, that of keeping an instance of an<br />
object easy to get to.</p>
<p>The <span>constructorArguments</span><br />
are, of course, how you pass in arguments to the class&#8217; constructor. Here we<br />
pass in, from the incoming event, the username, password, and from the <span class="Code"><span>scope</span></span> property of the</p>
<p><span class="Code"><span>EventMap</span></span>, a <span class="Code"><span>dispatcher</span></span>. Hopefully<br />
the event properties are clear enough to you. The dispatcher thing needs to be<br />
cleared up a bit though, I bet. What we&#8217;re going to do, since we don&#8217;t have a<br />
standard service to call, like a <span class="Code"><span>RemoteObject</span></span>, <span class="Code"><span>WebService</span></span>, or <span class="Code"><span>HTTPService</span></span>, which all have <a href="http://mate.asfusion.com/page/documentation/tags/services"><span>invokers</span></a> in Mate, is to have a delegate that<br />
dispatches events when things happen. To make that work with any Mate <span class="Code"><span>Listeners</span></span>, which<br />
we&#8217;ll see in a bit, we need to dispatch the events through Mate. This <span class="Code"><span>dispatcher</span></span> passed<br />
into the <span class="Code"><span>TwitterDelegate&#8217;s</span></span></p>
<p>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><u>MethodInvoker</u></span></span></a><br />
tag to invoke a method on the <span class="Code"><span>TwitterDelegate</span></span>,<br />
namely <span class="Code"><span>loadTimeline</span></span>.<br />
The <span class="Code"><span>MethodInvoker</span></span><br />
uses the same generator style. Since the defaults are in place on the <span class="Code"><span>ObjectBuilder</span></span>, the<br />
object that was built there will be reused here. In fact, We didn&#8217;t even really<br />
need to use the <span class="Code"><span>ObjectBuilder</span></span>,<br />
because the generator in <span class="Code"><span>MethodInvoker</span></span></p>
<p>would have cached the class too. That&#8217;s the default behavior of most of the<br />
tags used in the <span class="Code"><span>EventMap</span></span>.<br />
Why did I use the <span class="Code"><span>ObjectBuilder</span></span><br />
then? Just to show it could be done and to make it explicit. Look, I&#8217;m trying<br />
to teach here.</p>
<p>That was a lot of explanation for two or three tags, so let&#8217;s say<br />
it in plain English. When the <span class="Code"><span>EventMap</span></span><br />
gets the <span class="Code"><span>LoginEvent</span></span>,<br />
it builds a <span class="Code"><span>TwitterDelegate</span></span></p>
<p>and caches the instance for whenever another <span class="Code"><span>TwitterDelegate</span></span> is requested. Then we<br />
invoke <span class="Code"><span>loadTimeline</span></span><br />
on a <span class="Code"><span>TwitterDelegate</span></span>,<br />
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>dummyData</span></span> or not, and possibly call<br />
the Twitter service.</p>
<p><b>twitteria_mate/src/com/insideria/twitteria/business/TwitterDelegate.as<br />
#33-42 (formatted)</b></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
&lt;span class=&quot;category1&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;function&lt;/span&gt; loadTimeline():&lt;span class=&quot;category1&quot;&gt;void&lt;/span&gt; {<br />
&nbsp; &nbsp; &nbsp; &lt;span class=&quot;category1&quot;&gt;if&lt;/span&gt; (useDummyData) {<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;span class=&quot;category1&quot;&gt;var&lt;/span&gt; te:TwitterEvent = &lt;span class=&quot;category1&quot;&gt;new&lt;/span&gt; TwitterEvent(<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;TwitterEvent.ON_FRIENDS_TIMELINE_RESULT<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; );<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; te.&lt;span class=&quot;category2&quot;&gt;data&lt;/span&gt; = getDummyData();<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; friendsTimelineLoaded(te);<br />
&nbsp; &nbsp; &nbsp; &nbsp;} &lt;span class=&quot;category1&quot;&gt;else&lt;/span&gt; {<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; twitterService.loadFriendsTimeline(username);<br />
&nbsp; &nbsp; &nbsp; &nbsp;}<br />
}&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>And either way, the callback is executed.</p>
<p><b>twitteria_mate/src/com/insideria/twitteria/business/TwitterDelegate.as<br />
#53-56 (formatted)</b></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
&lt;span class=&quot;category1&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;function&lt;/span&gt; friendsTimelineLoaded(te:TwitterEvent):&lt;span class=&quot;category1&quot;&gt;void&lt;/span&gt; {<br />
&nbsp; &nbsp; &nbsp; &lt;span class=&quot;category1&quot;&gt;var&lt;/span&gt; e:TimelineReceivedEvent =<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;span class=&quot;category1&quot;&gt;new&lt;/span&gt; TimelineReceivedEvent(te.&lt;span class=&quot;category2&quot;&gt;data&lt;/span&gt; as &lt;span class=&quot;category2&quot;&gt;Array&lt;/span&gt;);<br />
&nbsp; &nbsp; &nbsp; dispatcher.dispatchEvent(e);<br />
}&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>This time it&#8217;s different, though, and we get together a <span class="Code"><span>TimelineReceivedEvent</span></span><br />
with the array of tweets and dispatch it through the dispatcher we got from the<br />
<span class="Code"><span>MainEventMap</span></span><br />
when the delegate was constructed.</p>
<p>The <span class="Code"><span>MainEventMap</span></span></p>
<p>is listening for that kind of event:</p>
<p><b>twitteria_mate/src/com/insideria/twitteria/maps/MainEventMap.mxml<br />
#18-21 (formatted)</b></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
&amp;lt;EventHandlers<br />
&nbsp; &nbsp; &nbsp;&lt;span class=&quot;category2&quot;&gt;type&lt;/span&gt;=&quot;&lt;span class=&quot;quote&quot;&gt;{TimelineReceivedEvent.TIMELINE_RECEIVED}&lt;/span&gt;&quot;<br />
&nbsp; &nbsp; &nbsp;debug=&quot;&lt;span class=&quot;quote&quot;&gt;true&lt;/span&gt;&quot;&amp;gt;<br />
<br />
&nbsp; &nbsp; &nbsp;&amp;lt;MethodInvoker<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; generator=&quot;&lt;span class=&quot;quote&quot;&gt;{TwitterManager}&lt;/span&gt;&quot;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;span class=&quot;category1&quot;&gt;method&lt;/span&gt;=&quot;&lt;span class=&quot;quote&quot;&gt;setCurrentTweets&lt;/span&gt;&quot;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;span class=&quot;category2&quot;&gt;arguments&lt;/span&gt;=&quot;&lt;span class=&quot;quote&quot;&gt;{[event.tweets]}&lt;/span&gt;&quot; /&amp;gt;<br />
&nbsp; &nbsp; &nbsp;&amp;lt;EventAnnouncer<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; generator=&quot;&lt;span class=&quot;quote&quot;&gt;{ViewStateEvent}&lt;/span&gt;&quot;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;span class=&quot;category2&quot;&gt;type&lt;/span&gt;=&quot;&lt;span class=&quot;quote&quot;&gt;{ViewStateEvent.SHOW_MAIN_VIEW}&lt;/span&gt;&quot;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; bubbles=&quot;&lt;span class=&quot;quote&quot;&gt;true&lt;/span&gt;&quot; /&amp;gt;<br />
<br />
&amp;lt;/EventHandlers&amp;gt;&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>When it gets it, it invokes <span class="Code"><span>setCurrentTweets</span></span> on a generated <span class="Code"><span>TwitterManager</span></span> and<br />
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><u>EventAnnouncer</u></span></span></a><br />
to fire a <span class="Code"><span>ViewStateEvent</span></span></p>
<p>of type <span class="Code"><span>ViewStateEvent.SHOW_MAIN_VIEW</span></span>.<br />
Let&#8217;s take those one at a time.</p>
<p>The <span class="Code"><span>TwitterManager</span></span><br />
is our model-type object, following what I take to be a Mate naming convention.<br />
It&#8217;s simple enough.</p>
<p><b>twitteria_mate/src/com/insideria/twitteria/business/TwitterManager.as<br />
#5-12 (formatted)</b></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
&lt;span class=&quot;category1&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;class&lt;/span&gt; TwitterManager {<br />
&nbsp; &nbsp; &nbsp; [Bindable]<br />
&nbsp; &nbsp; &nbsp; &lt;span class=&quot;category1&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;var&lt;/span&gt; currentTweets:ArrayCollection;<br />
<br />
&nbsp; &nbsp; &nbsp; &lt;span class=&quot;category1&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;function&lt;/span&gt; setCurrentTweets(tweets:&lt;span class=&quot;category2&quot;&gt;Array&lt;/span&gt;):&lt;span class=&quot;category1&quot;&gt;void&lt;/span&gt; {<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; currentTweets = &lt;span class=&quot;category1&quot;&gt;new&lt;/span&gt; ArrayCollection(tweets);<br />
&nbsp; &nbsp; &nbsp; &nbsp;}&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>It just has a <span>Bindable</span> collection of tweets and a way to set them. Now<br />
that they&#8217;re set, how do they get to the view? A <a href="http://mate.asfusion.com/page/documentation/tags/propertyinjector"><span>PropertyInjector</span></a>, with the help of Flex<br />
binding.</p>
<p><b>twitteria_mate/src/com/insideria/twitteria/maps/MainEventMap.mxml<br />
#31-33 (formatted)</b></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
&amp;lt;Injectors &lt;span class=&quot;category2&quot;&gt;target&lt;/span&gt;=&quot;&lt;span class=&quot;quote&quot;&gt;{MainView}&lt;/span&gt;&quot;&amp;gt;<br />
&nbsp; &nbsp; &nbsp;&amp;lt;PropertyInjector<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; source=&quot;&lt;span class=&quot;quote&quot;&gt;{TwitterManager}&lt;/span&gt;&quot;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sourceKey=&quot;&lt;span class=&quot;quote&quot;&gt;currentTweets&lt;/span&gt;&quot;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; targetKey=&quot;&lt;span class=&quot;quote&quot;&gt;currentTweets&lt;/span&gt;&quot; /&amp;gt;<br />
<br />
&amp;lt;/Injectors&amp;gt;&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>This is another very Mate way of doing things. This is saying<br />
that Mate should bind the <span class="Code"><span>currentTweets</span></span><br />
property of any cached <span class="Code"><span>TwitterManager</span></span><br />
into the cached <span class="Code"><span>MainView</span></span><br />
instance&#8217;s <span class="Code"><span>currentTweets</span></span>.<br />
Hold on, when did a <span class="Code"><span>MainView</span></span></p>
<p>get cached? Well, as a service to the user, Mate listens for the event from any<br />
view (I believe the <span class="Code"><span>creationComplete</span></span><br />
event) just like it does for any other user defined bubbling event, and then<br />
caches a reference to that view. That way the <span class="Code"><span>EventMap</span></span> has a way to communicate with<br />
the view of any type. Sneaky, eh? I thought so. Now whenever the <span class="Code"><span>currentTweets</span></span> on our<br />
manager changes, that view will be updated. Now we have the data getting to the<br />
right view, but how do we get the <span class="Code"><span>ViewStack</span></span> on the application onto the right index?</p>
<p>That second tag, the <span class="Code"><span>EventAnnouncer</span></span> fires off a <span class="Code"><span>ViewStateEvent</span></span>.</p>
<p><b>twitteria_mate/src/com/insideria/twitteria/events/ViewStateEvent.as<br />
#7-11 (formatted)</b></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
&lt;span class=&quot;category1&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;static&lt;/span&gt; const SHOW_MAIN_VIEW:&lt;span class=&quot;category2&quot;&gt;String&lt;/span&gt; = &quot;&lt;span class=&quot;quote&quot;&gt;showMainView&lt;/span&gt;&quot;;<br />
<br />
&lt;span class=&quot;category1&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;function&lt;/span&gt; ViewStateEvent(<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;span class=&quot;category2&quot;&gt;type&lt;/span&gt;:&lt;span class=&quot;category2&quot;&gt;String&lt;/span&gt;,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;bubbles:&lt;span class=&quot;category2&quot;&gt;Boolean&lt;/span&gt;=&lt;span class=&quot;category1&quot;&gt;true&lt;/span&gt;,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;cancelable:&lt;span class=&quot;category2&quot;&gt;Boolean&lt;/span&gt;=&lt;span class=&quot;category1&quot;&gt;false&lt;/span&gt;) {<br />
&nbsp; &nbsp; &nbsp; &lt;span class=&quot;category1&quot;&gt;super&lt;/span&gt;(&lt;span class=&quot;category2&quot;&gt;type&lt;/span&gt;, bubbles, cancelable);<br />
}&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>Since we&#8217;re using the <span class="Code"><span>EventAnnouncer</span></span> to fire this off, it needs the standard<br />
event constructor. Also, we could have lots of view state constants to use for<br />
different view state events since Flash events are unique by sort of a weird<br />
mix of class and type property. So where does this event go? Well, if we look<br />
back on the application, we&#8217;ll see.</p>
<p class="MsoNormal"><span>&nbsp;</span></p>
<p><b>twitteria_mate/src/twitteria_mate.mxml #23 (formatted)</b></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
&amp;lt;mate:Listener<br />
&nbsp; &nbsp; &nbsp;&lt;span class=&quot;category2&quot;&gt;type&lt;/span&gt;=&quot;&lt;span class=&quot;quote&quot;&gt;{ViewStateEvent.SHOW_MAIN_VIEW}&lt;/span&gt;&quot;<br />
&nbsp; &nbsp; &nbsp;&lt;span class=&quot;category1&quot;&gt;method&lt;/span&gt;=&quot;&lt;span class=&quot;quote&quot;&gt;showMainView&lt;/span&gt;&quot; /&amp;gt;&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>Here&#8217;s a <a href="http://mate.asfusion.com/page/documentation/tags/listener"><span class="Code"><span><u>Listener</u></span></span></a></p>
<p>tag that listens for just that event type. When it gets it, it calls <span class="Code"><span>showMainView</span></span>.</p>
<p><b>twitteria_mate/src/twitteria_mate.mxml #7-12</b></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
&lt;span class=&quot;category1&quot;&gt;public&lt;/span&gt; const LOGIN_VIEW:&lt;span class=&quot;category1&quot;&gt;int&lt;/span&gt; &nbsp; &nbsp;= 0;<br />
<br />
&lt;span class=&quot;category1&quot;&gt;public&lt;/span&gt; const MAIN_VIEW:&lt;span class=&quot;category1&quot;&gt;int&lt;/span&gt; &nbsp; &nbsp; = 1;<br />
<br />
&lt;span class=&quot;category1&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;function&lt;/span&gt; showMainView(e:Event):&lt;span class=&quot;category1&quot;&gt;void&lt;/span&gt; {<br />
&nbsp; &nbsp; &nbsp; mainViewStack.selectedIndex = MAIN_VIEW;<br />
}&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>That method sets the view stack to where it should be. Now we<br />
have the <span class="Code"><span>MainView</span></span><br />
showing in the <span class="Code"><span>ViewStack</span></span><br />
and right data in the list in <span class="Code"><span>MainView</span></span>.<br />
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.<br />
Here&#8217;s where we do it:</p>
<p><b>twitteria_mate/src/com/insideria/twitteria/view/MainView.mxml<br />
#12-16</b></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
&lt;span class=&quot;category1&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;function&lt;/span&gt; setStatus():&lt;span class=&quot;category1&quot;&gt;void&lt;/span&gt; {<br />
&nbsp; &nbsp; &nbsp; &lt;span class=&quot;category1&quot;&gt;var&lt;/span&gt; e:SetStatusEvent = &lt;span class=&quot;category1&quot;&gt;new&lt;/span&gt; SetStatusEvent(statusText.&lt;span class=&quot;category2&quot;&gt;text&lt;/span&gt;);<br />
&nbsp; &nbsp; &nbsp; dispatchEvent(e);<br />
&nbsp; &nbsp; &nbsp; statusText.&lt;span class=&quot;category2&quot;&gt;clear&lt;/span&gt;();<br />
}&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>And here&#8217;s where it ends up:</p>
<p><b>twitteria_mate/src/com/insideria/twitteria/maps/MainEventMap.mxml<br />
#23-25 (formatted)</b></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
&amp;lt;EventHandlers &lt;span class=&quot;category2&quot;&gt;type&lt;/span&gt;=&quot;&lt;span class=&quot;quote&quot;&gt;{SetStatusEvent.SET_STATUS}&lt;/span&gt;&quot; debug=&quot;&lt;span class=&quot;quote&quot;&gt;true&lt;/span&gt;&quot;&amp;gt;<br />
<br />
&nbsp; &nbsp; &nbsp;&amp;lt;MethodInvoker<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; generator=&quot;&lt;span class=&quot;quote&quot;&gt;{TwitterDelegate}&lt;/span&gt;&quot;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;span class=&quot;category1&quot;&gt;method&lt;/span&gt;=&quot;&lt;span class=&quot;quote&quot;&gt;setStatus&lt;/span&gt;&quot;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;span class=&quot;category2&quot;&gt;arguments&lt;/span&gt;=&quot;&lt;span class=&quot;quote&quot;&gt;{[event.statusText]}&lt;/span&gt;&quot; /&amp;gt;<br />
&amp;lt;/EventHandlers&amp;gt;&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>We call <span class="Code"><span>setStatus</span></span><br />
on the cached <span class="Code"><span>TwitterDelegate</span></span>,<br />
passing in the <span class="Code"><span>statusText</span></span><br />
from the incoming event.</p>
<p><b>twitteria_mate/src/com/insideria/twitteria/business/TwitterDelegate.as<br />
#58-61</b></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
&lt;span class=&quot;category1&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;function&lt;/span&gt; statusSet(te:TwitterEvent):&lt;span class=&quot;category1&quot;&gt;void&lt;/span&gt; {<br />
&nbsp; &nbsp; &nbsp; &lt;span class=&quot;category1&quot;&gt;var&lt;/span&gt; e:StatusSetEvent = &lt;span class=&quot;category1&quot;&gt;new&lt;/span&gt; StatusSetEvent();<br />
&nbsp; &nbsp; &nbsp; dispatcher.dispatchEvent(e);<br />
}&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>When the delegate is done, it dispatches a StatusSetEvent through<br />
its dispatcher.</p>
<p class="MsoNormal"><span>&nbsp;</span></p>
<p><b>twitteria_mate/src/com/insideria/twitteria/maps/MainEventMap.mxml<br />
#27-29 (formatted)</b></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
&amp;lt;EventHandlers &lt;span class=&quot;category2&quot;&gt;type&lt;/span&gt;=&quot;&lt;span class=&quot;quote&quot;&gt;{StatusSetEvent.STATUS_SET}&lt;/span&gt;&quot; debug=&quot;&lt;span class=&quot;quote&quot;&gt;true&lt;/span&gt;&quot;&amp;gt;<br />
<br />
&nbsp; &nbsp; &nbsp;&amp;lt;MethodInvoker<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; generator=&quot;&lt;span class=&quot;quote&quot;&gt;{TwitterDelegate}&lt;/span&gt;&quot;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;span class=&quot;category1&quot;&gt;method&lt;/span&gt;=&quot;&lt;span class=&quot;quote&quot;&gt;loadTimeline&lt;/span&gt;&quot; /&amp;gt;<br />
&amp;lt;/EventHandlers&amp;gt;&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>Back in the <span class="Code"><span>EventMap</span></span>,<br />
it catches that event and reloads by calling back to the delegate, which kicks<br />
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>EventMap</span></span> approach is<br />
novel, as is the class caching. Once you see how it works, it&#8217;s a lot of fun to<br />
use, though.</p>
<p>Now we&#8217;ve built our application using four different Flex<br />
frameworks. Again, although it wasn&#8217;t an exhaustive look at each framework or<br />
its capabilities, and since our use cases may have been a little out of the<br />
ordinary especially around the delegate area, I hope that this has at least<br />
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,<br />
where I tell you how I think each framework stacks up against the others, which<br />
one I&#8217;d like to use from now on, and which one I think renders the most<br />
Programmer Joy.<span></span></p>
<p><a href="http://www.insideria.com/tony-hillerson/">Read more from<br />
Tony Hillerson</a>.</p>


<p>Related posts:<ol><li><a href='http://flex.exposedout.net/2009/01/16/frameworkquest-2008-part-3-framework-agnostic-views-with-puremvc/' rel='bookmark' title='Permanent Link: FrameworkQuest 2008 Part 3: Framework Agnostic Views with PureMVC'>FrameworkQuest 2008 Part 3: Framework Agnostic Views with PureMVC</a></li>
<li><a href='http://flex.exposedout.net/2009/01/16/frameworkquest-2008-part-4-ioc-with-swiz/' rel='bookmark' title='Permanent Link: FrameworkQuest 2008 Part 4: IoC With Swiz'>FrameworkQuest 2008 Part 4: IoC With Swiz</a></li>
<li><a href='http://flex.exposedout.net/2009/01/16/frameworkquest-2008-part-2-get-control-with-cairngorm/' rel='bookmark' title='Permanent Link: FrameworkQuest 2008 Part 2: Get Control with Cairngorm'>FrameworkQuest 2008 Part 2: Get Control with Cairngorm</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://flex.exposedout.net/2009/01/16/frameworkquest-2008-part-5-mate-the-pure-mxml-framework/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>FrameworkQuest 2008 Part 4: IoC With Swiz</title>
		<link>http://flex.exposedout.net/2009/01/16/frameworkquest-2008-part-4-ioc-with-swiz/</link>
		<comments>http://flex.exposedout.net/2009/01/16/frameworkquest-2008-part-4-ioc-with-swiz/#comments</comments>
		<pubDate>Fri, 16 Jan 2009 11:02:09 +0000</pubDate>
		<dc:creator>Vikram singh</dc:creator>
				<category><![CDATA[flex]]></category>
		<category><![CDATA[framework]]></category>

		<guid isPermaLink="false">http://guavus.wordpress.com/?p=166</guid>
		<description><![CDATA[FrameworkQuest Part 4 by Tony Hillerson Find the original post here print listen FrameworkQuest 2008: Introduction FrameworkQuest 2008 Part 2: Get Control with Cairngorm FrameworkQuest 2008 Part 3: Agnostic Views with PureMVC FrameworkQuest 2008 Part 4: IoC With Swiz FrameworkQuest 2008 Part 5: Mate, the Pure MXML Framework FrameworkQuest 2008 Part 6: The Exciting Conclusion [...]


Related posts:<ol><li><a href='http://flex.exposedout.net/2009/01/16/frameworkquest-2008-part-2-get-control-with-cairngorm/' rel='bookmark' title='Permanent Link: FrameworkQuest 2008 Part 2: Get Control with Cairngorm'>FrameworkQuest 2008 Part 2: Get Control with Cairngorm</a></li>
<li><a href='http://flex.exposedout.net/2009/01/16/frameworkquest-2008-part-3-framework-agnostic-views-with-puremvc/' rel='bookmark' title='Permanent Link: FrameworkQuest 2008 Part 3: Framework Agnostic Views with PureMVC'>FrameworkQuest 2008 Part 3: Framework Agnostic Views with PureMVC</a></li>
<li><a href='http://flex.exposedout.net/2009/01/16/frameworkquest-2008-part-5-mate-the-pure-mxml-framework/' rel='bookmark' title='Permanent Link: FrameworkQuest 2008 Part 5: Mate, the Pure MXML Framework'>FrameworkQuest 2008 Part 5: Mate, the Pure MXML Framework</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>FrameworkQuest Part 4 by <strong>Tony Hillerson</strong><br />
Find the original post <a href="http://www.insideria.com/2008/12/frameworkquest-2008-part-4-ioc.html?CMP=AFC-ak_article&amp;ATT=FrameworkQuest+2008+Part+4%3A+IoC+With+Swiz">here</a></p>
<div class="button"><a href="http://www.insideria.com/print/33984.html" target="_blank">print <img src="http://insideria.com/riaimages/printtag.jpg" style="border:none;" /></a><br />
<a target="_new" href="http://asp2.readspeaker.net/cgi-bin/oreillyrsone?lang=us&amp;voice=Paul&amp;customerid=171&amp;url=http://www.insideria.com/2008/12/frameworkquest-2008-part-4-ioc.html">listen <img src="http://www.oreillynet.com/images/icon_listen_small.gif" width="10" height="9" alt="Speech Icon" /></a></div>
<blockquote><p>
<a href="http://www.insideria.com/2008/12/frameworkquest-2008-introducti.html">FrameworkQuest 2008: Introduction</a><br />
<a href="http://www.insideria.com/2008/12/frameworkquest-2008-part-2-get.html?CMP=AFC-ak_article&amp;ATT=FrameworkQuest+2008++Part+2%3A+Get+Control+with+Cairngorm">FrameworkQuest 2008 Part 2: Get Control with Cairngorm</a><br />
<a href="http://www.insideria.com/2008/12/frameworkquest-2008-part-3-fra.html?CMP=AFC-ak_article&amp;ATT=FrameworkQuest+2008+Part+3%3A+Framework+Agnostic+Views+with+PureMVC">FrameworkQuest 2008 Part 3: Agnostic Views with PureMVC</a><br />
<a href="http://www.insideria.com/2008/12/frameworkquest-2008-part-4-ioc.html?CMP=AFC-ak_article&amp;ATT=FrameworkQuest+2008+Part+4%3A+IoC+With+Swiz">FrameworkQuest 2008 Part 4: IoC With Swiz</a><br />
<a href="http://www.insideria.com/2008/12/frameworkquest-2008-part-5-mat.html?CMP=AFC-ak_article&amp;ATT=FrameworkQuest+2008+Part+5%3A+Mate%2c+the+Pure+MXML+Framework">FrameworkQuest 2008 Part 5: Mate, the Pure MXML Framework</a><br />
<a href="http://www.insideria.com/2009/01/frameworkquest-2008-part-6-the.html?CMP=AFC-ak_article&amp;ATT=FrameworkQuest+2008+Part+6%3A+The+Exciting+Conclusion">FrameworkQuest 2008 Part 6: The Exciting Conclusion</a>
</p></blockquote>
<p>With a name like <a href="http://swizframework.googlecode.com"><span>Swiz</span></a>, it has to be good, right? Welcome back,<br />
friends, to part four of our ongoing effort to understand these four Flex<br />
frameworks. This time we&#8217;re going to look at Swiz, a relative newcomer, created<br />
by <a href="http://cdscott.blogspot.com/"><span>Chris<br />
Scott</span></a>. Chris had a simple idea to use a powerful but underused Flex<br />
feature, Metadata, to implement a concept called Inversion of Control.</p>
<p>Sounds scary? Actually, the point of this effort is to make<br />
things easier for you. A big part of the frameworks we&#8217;ve looked at so far is<br />
not just some classes that you have to create, but some wiring you have to do.<br />
You have to make some framework classes, describe them to the framework, and<br />
make sure that the code describing them gets called. That overhead can feel<br />
like a drag on productivity and maintainability. That&#8217;s one thing that<br />
Inversion of Control is made to fix.</p>
<p>Here&#8217;s an example of what we&#8217;re talking about. Remember last week<br />
when we set up <span class="Code"><span>Mediators</span></span><br />
to work with the application view, <span class="Code"><span>LoginView</span></span>, and <span class="Code"><span>MainView</span></span>? We fired off a PureMVC command called <span class="Code"><span>ViewPrepCommand</span></span> that<br />
reached in and got the reference to each view, created an <span class="Code"><span>ApplicationMediator</span></span>, <span class="Code"><span>LoginViewMediator</span></span>, <span class="Code"><span>MainViewMediator</span></span>, and passed the views<br />
in to each. It doesn&#8217;t make any difference that we pushed that code into a<br />
Command to keep the view clean, we still had to write the code to take those<br />
steps. Same thing when we wrote the code to associate <span class="Code"><span>LoginEvent</span></span> with <span class="Code"><span>LoginCommand</span></span> in the <span class="Code"><span>TwitteRIAController</span></span> in the Cairngorm<br />
example. We had to go one place to write the code for the event, another place<br />
to write the code for the command, and then another to say that we wanted the<br />
one to associate with the other. Wouldn&#8217;t it be nice if we could, with a<br />
minimum amount of code, ask the framework to do that for us?</p>
<p>Consider Flex Binding. Lovely, isn&#8217;t it? You mark a property as <span class="Code"><span>[Bindable]</span></span>, and then<br />
elsewhere you can use the curly brace notation to tell Flex that you want to<br />
wire that value up to another property and update that destination property<br />
whenever the other changes. This is a lot like Inversion of Control.</p>
<p>The control that we&#8217;re talking about here is actually a<br />
responsibility &#8211; responsibility to get the resources that a particular<br />
component needs in place. In the current paradigm we&#8217;ve been working with, the<br />
component, or a delegate that we create, is responsible for getting the<br />
component&#8217;s stuff together. IoC means to invert that responsibility up out of<br />
the component and into the framework. Instead of going to find and wire up what<br />
it wants, a component instead just lets the framework knows what it wants, and<br />
the framework does the rest. This requires the component to have knowledge of<br />
the framework, but not to have to know the details of where to get things. </p>
<p>We&#8217;ll get to see IoC in action with Swiz in a bit, but first<br />
let&#8217;s talk for a second, as we have with the other frameworks, about how the<br />
Swiz flow of events works.</p>
<p>Pretty simple, eh? The user interacts with the view and the view<br />
notifies the <span class="Code"><span>Controller</span></span>.<br />
How that happens is up to you. You could use events and set the <span class="Code"><span>Controller</span></span> up as an<br />
event listener, or you could call the <span class="Code"><span>Controller</span></span> directly. If there&#8217;s service work to be done,<br />
the <span class="Code"><span>Controller</span></span></p>
<p>will call a <span class="Code"><span>Delegate</span></span><br />
and the <span class="Code"><span>Delegate</span></span><br />
can call the service. Swiz makes it dead simple to wire up the <span class="Code"><span>Controller</span></span>/<span class="Code"><span>Delegate</span></span><br />
communication &#8211; IF &#8211; the service is an AMF service that you can contact with a <span class="Code"><span>RemoteObject</span></span>. If the<br />
service is not a <span class="Code"><span>RemoteObject</span></span><br />
you have to fend for yourself as I found out. More on that in a bit.</p>
<p>When the service call is over and the <span class="Code"><span>Controller</span></span> gets notified, the<br />
controller can put some data on the model and act on the view as necessary. The<br />
<span class="Code"><span>Controller</span></span> is<br />
free to wire up data from the <span class="Code"><span>Model</span></span><br />
to the view PureMVC style, or you can use Binding and let Flex do the work.</p>
<p><img /></p>
<p>Again, pretty simple. But it&#8217;s no more than you need to get the job done. The app is separated<br />
into the three concerns, services are encapsulated, and the best part, which<br />
we&#8217;ll see next, is that Swiz takes care of wiring all this stuff together. </p>
<p><strong>You Turn Me Right &#8216;Round, Baby</strong></p>
<p>That&#8217;s an IoC joke, right there. Moving along let&#8217;s look in the<br />
root application to see some characteristic Swiz code. </p>
<p><b>twitteria_swiz/src/twitteria_swiz.mxml #20-22</b></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
[Bindable]<br />
<br />
[Autowire(bean=&quot;&lt;span class=&quot;quote&quot;&gt;model&lt;/span&gt;&quot;)]<br />
<br />
&lt;span class=&quot;category1&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;var&lt;/span&gt; model:TwitteRIAModel;&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>This is the reference to the model that the application uses to<br />
drive the <span class="Code"><span>ViewStack</span></span>,<br />
as it does in the Cairngorm application. You&#8217;ve seen a <span>[</span><span>Bindable</span><span>]</span> tag before, but what&#8217;s that other tag underneath there? <span class="Code"><span>Autowire</span></span> is a Swiz<br />
metadata tag. Flex has had <a href="http://livedocs.adobe.com/flex/3/html/help.html?content=metadata_3.html"><span>metadata</span></a> around for a while, but recently<br />
allowed a compiler option to keep <a href="http://coenraets.org/blog/2007/10/annotating-actionscript-classes-with-custom-metadata-simple-orm-framework-for-air/"><span>custom metadata</span></a>. The Swiz swc library adds two<br />
tags to the list of metadata that the Flex compiler will keep around, <span class="Code"><span>Autowire</span></span>, and <span class="Code"><span>Mediate</span></span>. We&#8217;ll look<br />
at <span class="Code"><span>Mediate</span></span> in a<br />
bit, but <span class="Code"><span>Autowire</span></span></p>
<p>is the first example of Swiz&#8217;s IoC at work. It&#8217;s essentially saying &#8220;When this<br />
view is constructed, go find a <i>bean</i><span><br />
named &#8216;model&#8217; and set this property, </span><span class="Code"><span>model</span></span>, to point to it&#8221;. If you&#8217;ve come<br />
from Java-land to Flex, you know what we mean by <i>bean</i><span>, but others may not. Lots of talk about beans in<br />
Java-land, for those of you who don&#8217;t know, but all they mean is some sort of<br />
component. Don&#8217;t worry about it, and feel free to make as many jokes as you want.<br />
As far as I&#8217;m concerned, they&#8217;re all deserved. Beans! Come on. Don&#8217;t even get<br />
me started on POJOs. </span></p>
<p>In case you didn&#8217;t notice, this <span class="Code"><span>Autowire</span></span> thing is sweet. We don&#8217;t have<br />
to worry about where this model comes from. We don&#8217;t have to think about if it&#8217;s<br />
a Singleton or not. All we know is that we want a model, and the framework will<br />
make sure we have one when we need it. One note of caution: the property has to<br />
be marked <span>public</span><br />
or Swiz won&#8217;t be able to assign to it.</p>
<p>So where do these magical beans come from? Well, there is one bit<br />
of administrativa we need to take care of to get those beans jumping for us.</p>
<p><b>twitteria_swiz/src/twitteria_swiz.mxml #8, 24-26</b></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
preinitialize=&quot;&lt;span class=&quot;quote&quot;&gt;loadBeans()&lt;/span&gt;&quot;<br />
...<br />
<br />
&lt;span class=&quot;category1&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;function&lt;/span&gt; loadBeans():&lt;span class=&quot;category1&quot;&gt;void&lt;/span&gt; {<br />
&nbsp; &nbsp; &nbsp; Swiz.loadBeans([Beans]);<br />
}&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>On <span class="Code"><span>preinitialize</span></span>,<br />
which is very early in the Flex bootstrapping process, we call <span class="Code"><span>loadBeans</span></span>, which<br />
delegates up to Swiz and mentions where to find them. It&#8217;s important that this<br />
happen at <span class="Code"><span>preinitialize</span></span><br />
so that Swiz is all ready to go when views that use Swiz metadata are created,<br />
including the application itself. Now let&#8217;s look at the bean definition file.</p>
<p><b>twitteria_swiz/src/com/insideria/twitteria/Beans.mxml </b></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
&amp;lt;BeanLoader<br />
&nbsp; &nbsp; &nbsp;xmlns=&quot;&lt;span class=&quot;quote&quot;&gt;org.swizframework.util.*&lt;/span&gt;&quot;<br />
&nbsp; &nbsp; &nbsp;xmlns:api=&quot;&lt;span class=&quot;quote&quot;&gt;twitter.api.*&lt;/span&gt;&quot;<br />
&nbsp; &nbsp; &nbsp;xmlns:delegates=&quot;&lt;span class=&quot;quote&quot;&gt;com.insideria.twitteria.delegates.*&lt;/span&gt;&quot;<br />
&nbsp; &nbsp; &nbsp;xmlns:model=&quot;&lt;span class=&quot;quote&quot;&gt;com.insideria.twitteria.model.*&lt;/span&gt;&quot;<br />
&nbsp; &nbsp; &nbsp;xmlns:controllers=&quot;&lt;span class=&quot;quote&quot;&gt;com.insideria.twitteria.controllers.*&lt;/span&gt;&quot;&amp;gt;<br />
<br />
&nbsp; &nbsp; &nbsp;&amp;lt;controllers:ApplicationController id=&quot;&lt;span class=&quot;quote&quot;&gt;applicationController&lt;/span&gt;&quot; /&amp;gt;<br />
&nbsp; &nbsp; &nbsp;&amp;lt;controllers:LoginViewController id=&quot;&lt;span class=&quot;quote&quot;&gt;loginViewController&lt;/span&gt;&quot; /&amp;gt;<br />
&nbsp; &nbsp; &nbsp;&amp;lt;controllers:MainViewController id=&quot;&lt;span class=&quot;quote&quot;&gt;mainViewController&lt;/span&gt;&quot; /&amp;gt;<br />
&nbsp; &nbsp; &nbsp;&amp;lt;model:TwitteRIAModel id=&quot;&lt;span class=&quot;quote&quot;&gt;model&lt;/span&gt;&quot; /&amp;gt;<br />
<br />
&amp;lt;/BeanLoader&amp;gt;&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>This <span class="Code"><span>BeanLoader</span></span><br />
is just an MXML file with a tag for any class that you want to <span class="Code"><span>Autowire</span></span> anywhere in<br />
the application. Inside we have all the controllers and the model. Notice that<br />
the call to <span class="Code"><span>loadBeans</span></span><br />
passes an array, so it&#8217;s possible to split up the bean definitions over<br />
multiple files for good housekeeping.</p>
<p>I decided to use the Flex binding way of wiring up the view to<br />
the model, so that instance that points at model is fair game, just as if we&#8217;d<br />
looked it up as a Singleton, a la Cairngorm, or gotten ahold of it some other<br />
way.</p>
<p><b>twitteria_swiz/src/twitteria_swiz.mxml #37 (formatted)</b></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
&amp;lt;mx:ViewStack selectedIndex=&quot;&lt;span class=&quot;quote&quot;&gt;{model.mainViewIndex}&lt;/span&gt;&quot;&amp;gt;&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p><strong>Logging In</strong></p>
<p>Just as before, when pressing enter in the password field on<br />
LoginView, the login process is kicked off. Here&#8217;s what it looks like with<br />
Swiz.</p>
<p><b>twitteria_swiz/src/com/insideria/twitteria/view/LoginView.mxml<br />
#9-14 (formatted)</b></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
&lt;span class=&quot;category1&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;function&lt;/span&gt; login():&lt;span class=&quot;category1&quot;&gt;void&lt;/span&gt; {<br />
&nbsp; &nbsp; &nbsp; &lt;span class=&quot;category1&quot;&gt;var&lt;/span&gt; e:DynamicEvent = &lt;span class=&quot;category1&quot;&gt;new&lt;/span&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;DynamicEvent(LoginViewController.LOG_IN);<br />
&nbsp; &nbsp; &nbsp; e.username = usernameText.&lt;span class=&quot;category2&quot;&gt;text&lt;/span&gt;;<br />
&nbsp; &nbsp; &nbsp; e.&lt;span class=&quot;category2&quot;&gt;password&lt;/span&gt; = passwordText.&lt;span class=&quot;category2&quot;&gt;text&lt;/span&gt;;<br />
&nbsp; &nbsp; &nbsp; Swiz.dispatchEvent(e);<br />
}&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>First thing we do is to created a <span class="Code"><span>DynamicEvent</span></span>, which is a little used<br />
(as far as I know) Flex event that is a dynamic class. That means we can assign<br />
to whatever properties we want on it, just like ActionScript&#8217;s <span class="Code"><span>Object</span></span>. Swiz doesn&#8217;t<br />
mandate the use of <span class="Code"><span>DynamicEvents</span></span>,<br />
but it slyly suggests that we can use this class instead of the more<br />
time-consuming method of creating a new Event for each type of payload. Just<br />
remember if you use dynamic objects that the compiler won&#8217;t catcher errors for<br />
you if you misspell things, but that&#8217;s what <a href="http://code.google.com/p/fluint/"><span>unit tests</span></a><br />
are for, right?</p>
<p>Our payload this time is the username and password. Instead of<br />
dispatching an event the regular way, we dispatch events through Swiz if we<br />
want framework classes to get them. Notice that there&#8217;s no controller instance<br />
specified on the <span class="Code"><span>LoginView</span></span>,<br />
nor does <span class="Code"><span>LoginViewController</span></span><br />
know anything about the view (although both could be true if the application<br />
needed it), but <span class="Code"><span>LoginViewController</span></span><br />
is still out there waiting for this <span class="Code"><span>LOG_IN</span></span> event, because it was instantiated in the <span class="Code"><span>BeanLoader</span></span>. How does<br />
the controller sign up to get events? Like this:</p>
<p><b>twitteria_swiz/src/com/insideria/twitteria/controllers/LoginViewController.as<br />
#18-25 </b></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
[Mediate(event=&quot;&lt;span class=&quot;quote&quot;&gt;login&lt;/span&gt;&quot;, properties=&quot;&lt;span class=&quot;quote&quot;&gt;username,password&lt;/span&gt;&quot;)]<br />
&lt;span class=&quot;category1&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;function&lt;/span&gt; login(username:&lt;span class=&quot;category2&quot;&gt;String&lt;/span&gt;, &lt;span class=&quot;category2&quot;&gt;password&lt;/span&gt;:&lt;span class=&quot;category2&quot;&gt;String&lt;/span&gt;):&lt;span class=&quot;category1&quot;&gt;void&lt;/span&gt; {<br />
&nbsp; &nbsp; &nbsp; model.username = username;<br />
&nbsp; &nbsp; &nbsp; model.&lt;span class=&quot;category2&quot;&gt;password&lt;/span&gt; = &lt;span class=&quot;category2&quot;&gt;password&lt;/span&gt;;<br />
&nbsp; &nbsp; &nbsp; &lt;span class=&quot;category1&quot;&gt;var&lt;/span&gt; e:Event = &lt;span class=&quot;category1&quot;&gt;new&lt;/span&gt; Event(LOGIN_COMPLETE);<br />
&nbsp; &nbsp; &nbsp; Swiz.dispatchEvent(e);<br />
}&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>Here&#8217;s the other metadata tag we mentioned, <span class="Code"><span>Mediate</span></span>. The <span class="Code"><span>Mediate</span></span> tag goes on controller methods<br />
that you want called when a certain type of event is dispatched through Swiz.<br />
The event argument to the tag needs to match the string type of the event, but<br />
sadly it&#8217;s not possible to make this point to the same constant that defines<br />
that string at this point. Just keep an eye out that they&#8217;re the same.</p>
<p>The tag&#8217;s properties argument tells Swiz which properties of the<br />
incoming event it should grab and pass into the tagged method. The gain is that<br />
you don&#8217;t have to add an event listener somewhere else, you have the code right<br />
here annotating the method. Also, you don&#8217;t have to do the boilerplate event<br />
wrangling to get data you need out. You say what data you&#8217;re expecting and from<br />
what type of event, and the framework will get it out for you. That means you<br />
can just write regular functions, which has the added benefit of letting you<br />
call those functions from other code that doesn&#8217;t use events. I didn&#8217;t test it,<br />
so don&#8217;t quote me on it, but it&#8217;s also theoretically possible to have more than<br />
one <span class="Code"><span>Mediate</span></span> tag<br />
per method, I suppose.</p>
<p>Inside the <span class="Code"><span>login</span></span><br />
method we set the username and password on the model, which is, of course, <span class="Code"><span>Autowired</span></span> up on the<br />
controller as well.</p>
<p><b>twitteria_swiz/src/com/insideria/twitteria/controllers/LoginViewController.as<br />
#15-16</b></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
[Autowire(bean=&quot;&lt;span class=&quot;quote&quot;&gt;model&lt;/span&gt;&quot;)]<br />
<br />
&lt;span class=&quot;category1&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;var&lt;/span&gt; model:TwitteRIAModel;&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>After setting those properties on the model, it then dispatches<br />
an event saying that log in is complete. Notice that instead of a <span class="Code"><span>DynamicEvent</span></span>, we&#8217;re<br />
using just a regular Flash <span class="Code"><span>Event</span></span></p>
<p>here. Either one will work, and <span class="Code"><span>Event</span></span><br />
is fine when we don&#8217;t have to carry a payload.</p>
<p>The next step after logging in is loading the timeline, and we do<br />
that on the <span class="Code"><span>MainViewController</span></span>.</p>
<p><strong>Loading The Timeline</strong></p>
<p>When the <span class="Code"><span>MainViewController</span></span><br />
is instantiated from the <span class="Code"><span>BeanLoader</span></span>,<br />
it registers to receive the log in event right away.</p>
<p><b>twitteria_swiz/src/com/insideria/twitteria/controllers/MainViewController.as<br />
#22-24</b></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
<br />
&lt;span class=&quot;category1&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;function&lt;/span&gt; MainViewController() {<br />
&nbsp; &nbsp; &nbsp; Swiz.addEventListener(<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;LoginViewController.LOGIN_COMPLETE,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;loginComplete<br />
&nbsp; &nbsp; &nbsp; );<br />
}&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>This is another way to listen for events sent through Swiz<br />
besides <span class="Code"><span>Mediate</span></span>.<br />
Once the event is received, <span>loginComplete</span><br />
is called.</p>
<p><b>twitteria_swiz/src/com/insideria/twitteria/controllers/MainViewController.as<br />
#53-55</b></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
&lt;span class=&quot;category1&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;function&lt;/span&gt; loginComplete(e:Event):&lt;span class=&quot;category1&quot;&gt;void&lt;/span&gt; {<br />
&nbsp; &nbsp; &nbsp; loadTweets();<br />
}&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p><b>twitteria_swiz/src/com/insideria/twitteria/controllers/MainViewController.as<br />
#31-34</b></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
&lt;span class=&quot;category1&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;function&lt;/span&gt; loadTweets():&lt;span class=&quot;category1&quot;&gt;void&lt;/span&gt; {<br />
&nbsp; &nbsp; &nbsp; &lt;span class=&quot;category1&quot;&gt;var&lt;/span&gt; delegate:TwitterDelegate = &lt;span class=&quot;category1&quot;&gt;new&lt;/span&gt; TwitterDelegate(&lt;span class=&quot;category1&quot;&gt;this&lt;/span&gt;);<br />
&nbsp; &nbsp; &nbsp; delegate.loadTimeline(username);<br />
}&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>Now comes the point where we call the delegate to get the latest<br />
timeline. Now, as I mentioned before this part is really easy if you&#8217;re using a<br />
service that is wrapped by a <span class="Code"><span>RemoteObject</span></span>.<br />
Then all you&#8217;d do is call <span class="Code"><span>createCommand</span></span>,<br />
passing the delegate method to call, its arguments, and a result and fault<br />
callback. As long as the delegate method returned an <span class="Code"><span>AsyncToken</span></span> object, Swiz would then<br />
take care of all the callbacks. That&#8217;s a nice set up, but unfortunately it<br />
doesn&#8217;t work for us, because we&#8217;re not using an AMF service.</p>
<p>What I did instead was hack together a more elaborate and<br />
depressing solution where I made an interface that I force any object calling<br />
the delegate to implement.</p>
<p><b>twitteria_swiz/src/com/insideria/twitteria/delegates/TwitterResponder.as<br />
#3-10 (formatted)</b></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
&lt;span class=&quot;category1&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;interface&lt;/span&gt; TwitterResponder {<br />
&nbsp; &nbsp; &nbsp; &lt;span class=&quot;category1&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;category2&quot;&gt;get&lt;/span&gt; username():&lt;span class=&quot;category2&quot;&gt;String&lt;/span&gt;;<br />
&nbsp; &nbsp; &nbsp; &lt;span class=&quot;category1&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;category2&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;category2&quot;&gt;password&lt;/span&gt;():&lt;span class=&quot;category2&quot;&gt;String&lt;/span&gt;;<br />
&nbsp; &nbsp; &nbsp; &lt;span class=&quot;category1&quot;&gt;function&lt;/span&gt; friendsTimelineResult(tweets:&lt;span class=&quot;category2&quot;&gt;Array&lt;/span&gt;):&lt;span class=&quot;category1&quot;&gt;void&lt;/span&gt;;<br />
&nbsp; &nbsp; &nbsp; &lt;span class=&quot;category1&quot;&gt;function&lt;/span&gt; setStatusResult():&lt;span class=&quot;category1&quot;&gt;void&lt;/span&gt;;<br />
}&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>Then I can make sure I know how the instance of the delegate<br />
should get the username and password, and that there&#8217;s a callback method for<br />
getting the timeline and status results. I&#8217;m sure there&#8217;s an easier way, but<br />
this occurred to me at the time. Some time in the future, I&#8217;d like to help Swiz<br />
out of this mess and make it just as easy to arbitrarily work with delegates<br />
that call any type of service. We&#8217;ll see if the time presents itself.</p>
<p>So now calling the delegate, which is the same old guy we&#8217;ve been<br />
using from project to project, will call back to <span>friendsTimelineResult</span> on the controller when the<br />
timeline is loaded, which sets the collection on the model.</p>
<p><b>twitteria_swiz/src/com/insideria/twitteria/controllers/MainViewController.as<br />
#44-46</b></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
&lt;span class=&quot;category1&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;function&lt;/span&gt; friendsTimelineResult(tweets:&lt;span class=&quot;category2&quot;&gt;Array&lt;/span&gt;):&lt;span class=&quot;category1&quot;&gt;void&lt;/span&gt; {<br />
&nbsp; &nbsp; &nbsp; model.currentTweets = &lt;span class=&quot;category1&quot;&gt;new&lt;/span&gt; ArrayCollection(tweets);<br />
}&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>Binding takes over from there and the new list is shown in <span class="Code"><span>MainView</span></span>.</p>
<p><strong>Setting Status</strong></p>
<p>Just as before, pressing enter in the status text field will kick<br />
off the chain of events to set status.</p>
<p><b>twitteria_swiz/src/com/insideria/twitteria/view/MainView.mxml<br />
#15-18</b></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
&lt;span class=&quot;category1&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;function&lt;/span&gt; setStatus():&lt;span class=&quot;category1&quot;&gt;void&lt;/span&gt; {<br />
&nbsp; &nbsp; &nbsp; controller.setStatus(statusText.&lt;span class=&quot;category2&quot;&gt;text&lt;/span&gt;);<br />
&nbsp; &nbsp; &nbsp; statusText.&lt;span class=&quot;category2&quot;&gt;clear&lt;/span&gt;();<br />
}&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>This time we again elected to call up to the controller.</p>
<p><b>twitteria_swiz/src/com/insideria/twitteria/controllers/MainViewController.as<br />
#26-29</b></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
&lt;span class=&quot;category1&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;function&lt;/span&gt; setStatus(statusMessage:&lt;span class=&quot;category2&quot;&gt;String&lt;/span&gt;):&lt;span class=&quot;category1&quot;&gt;void&lt;/span&gt; {<br />
&nbsp; &nbsp; &nbsp; &lt;span class=&quot;category1&quot;&gt;var&lt;/span&gt; delegate:TwitterDelegate = &lt;span class=&quot;category1&quot;&gt;new&lt;/span&gt; TwitterDelegate(&lt;span class=&quot;category1&quot;&gt;this&lt;/span&gt;);<br />
&nbsp; &nbsp; &nbsp; delegate.setStatus(statusMessage);<br />
}&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>The controller calls out to the delegate, and the delegate<br />
returns to say that the status is set, so we kick off a load timeline again to<br />
get the latest tweets.</p>
<p><b>twitteria_swiz/src/com/insideria/twitteria/controllers/MainViewController.as<br />
#48-51</b></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
&lt;span class=&quot;category1&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;function&lt;/span&gt; setStatusResult():&lt;span class=&quot;category1&quot;&gt;void&lt;/span&gt; {<br />
&nbsp; &nbsp; &nbsp; &lt;span class=&quot;linecomment&quot;&gt;// reload tweets to get the newest&lt;/span&gt;<br />
<br />
&nbsp; &nbsp; &nbsp; loadTweets();<br />
}&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>And that&#8217;s the Swiz version, folks!</p>
<p><strong>Next Up</strong></p>
<p>I&#8217;m supposed to be leaving the evaluations until the last<br />
article, but I will say right away that Swiz certainly delivers on its promise<br />
of cutting down boilerplate code. It&#8217;s a breeze to work with, and the only<br />
tough spot is if you&#8217;re not using an AMF service.</p>
<p>Next time we&#8217;re going to look at our last framework, Mate, and<br />
see how it takes advantage of MXML to make a simple, declarative Flex<br />
framework.<span></span></p>
<p><a href="http://www.insideria.com/tony-hillerson/">Read more from<br />
Tony Hillerson</a>.</p>


<p>Related posts:<ol><li><a href='http://flex.exposedout.net/2009/01/16/frameworkquest-2008-part-2-get-control-with-cairngorm/' rel='bookmark' title='Permanent Link: FrameworkQuest 2008 Part 2: Get Control with Cairngorm'>FrameworkQuest 2008 Part 2: Get Control with Cairngorm</a></li>
<li><a href='http://flex.exposedout.net/2009/01/16/frameworkquest-2008-part-3-framework-agnostic-views-with-puremvc/' rel='bookmark' title='Permanent Link: FrameworkQuest 2008 Part 3: Framework Agnostic Views with PureMVC'>FrameworkQuest 2008 Part 3: Framework Agnostic Views with PureMVC</a></li>
<li><a href='http://flex.exposedout.net/2009/01/16/frameworkquest-2008-part-5-mate-the-pure-mxml-framework/' rel='bookmark' title='Permanent Link: FrameworkQuest 2008 Part 5: Mate, the Pure MXML Framework'>FrameworkQuest 2008 Part 5: Mate, the Pure MXML Framework</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://flex.exposedout.net/2009/01/16/frameworkquest-2008-part-4-ioc-with-swiz/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>FrameworkQuest 2008 Part 3: Framework Agnostic Views with PureMVC</title>
		<link>http://flex.exposedout.net/2009/01/16/frameworkquest-2008-part-3-framework-agnostic-views-with-puremvc/</link>
		<comments>http://flex.exposedout.net/2009/01/16/frameworkquest-2008-part-3-framework-agnostic-views-with-puremvc/#comments</comments>
		<pubDate>Fri, 16 Jan 2009 10:59:05 +0000</pubDate>
		<dc:creator>Vikram singh</dc:creator>
				<category><![CDATA[flex]]></category>
		<category><![CDATA[framework]]></category>

		<guid isPermaLink="false">http://guavus.wordpress.com/?p=163</guid>
		<description><![CDATA[FrameworkQuest Part 3 by Tony Hillerson Find the original post here print listen FrameworkQuest 2008: Introduction FrameworkQuest 2008 Part 2: Get Control with Cairngorm FrameworkQuest 2008 Part 3: Agnostic Views with PureMVC FrameworkQuest 2008 Part 4: IoC With Swiz FrameworkQuest 2008 Part 5: Mate, the Pure MXML Framework FrameworkQuest 2008 Part 6: The Exciting Conclusion [...]


Related posts:<ol><li><a href='http://flex.exposedout.net/2009/01/16/frameworkquest-2008-part-5-mate-the-pure-mxml-framework/' rel='bookmark' title='Permanent Link: FrameworkQuest 2008 Part 5: Mate, the Pure MXML Framework'>FrameworkQuest 2008 Part 5: Mate, the Pure MXML Framework</a></li>
<li><a href='http://flex.exposedout.net/2009/01/16/frameworkquest-2008-part-6-the-exciting-conclusion/' rel='bookmark' title='Permanent Link: FrameworkQuest 2008 Part 6: The Exciting Conclusion'>FrameworkQuest 2008 Part 6: The Exciting Conclusion</a></li>
<li><a href='http://flex.exposedout.net/2009/01/16/frameworkquest-2008-part-4-ioc-with-swiz/' rel='bookmark' title='Permanent Link: FrameworkQuest 2008 Part 4: IoC With Swiz'>FrameworkQuest 2008 Part 4: IoC With Swiz</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>FrameworkQuest Part 3 by <strong>Tony Hillerson</strong><br />
Find the original post <a href="http://www.insideria.com/2008/12/frameworkquest-2008-part-3-fra.html?CMP=AFC-ak_article&amp;ATT=FrameworkQuest+2008+Part+3%3A+Framework+Agnostic+Views+with+PureMVC">here</a></p>
<div class="button"><a href="http://www.insideria.com/print/33983.html" target="_blank">print <img src="http://insideria.com/riaimages/printtag.jpg" style="border:none;" /></a><br />
<a target="_new" href="http://asp2.readspeaker.net/cgi-bin/oreillyrsone?lang=us&amp;voice=Paul&amp;customerid=171&amp;url=http://www.insideria.com/2008/12/frameworkquest-2008-part-3-fra.html">listen <img src="http://www.oreillynet.com/images/icon_listen_small.gif" width="10" height="9" alt="Speech Icon" /></a></div>
<blockquote><p>
<a href="http://www.insideria.com/2008/12/frameworkquest-2008-introducti.html">FrameworkQuest 2008: Introduction</a><br />
<a href="http://www.insideria.com/2008/12/frameworkquest-2008-part-2-get.html?CMP=AFC-ak_article&amp;ATT=FrameworkQuest+2008++Part+2%3A+Get+Control+with+Cairngorm">FrameworkQuest 2008 Part 2: Get Control with Cairngorm</a><br />
<a href="http://www.insideria.com/2008/12/frameworkquest-2008-part-3-fra.html?CMP=AFC-ak_article&amp;ATT=FrameworkQuest+2008+Part+3%3A+Framework+Agnostic+Views+with+PureMVC">FrameworkQuest 2008 Part 3: Agnostic Views with PureMVC</a><br />
<a href="http://www.insideria.com/2008/12/frameworkquest-2008-part-4-ioc.html?CMP=AFC-ak_article&amp;ATT=FrameworkQuest+2008+Part+4%3A+IoC+With+Swiz">FrameworkQuest 2008 Part 4: IoC With Swiz</a><br />
<a href="http://www.insideria.com/2008/12/frameworkquest-2008-part-5-mat.html?CMP=AFC-ak_article&amp;ATT=FrameworkQuest+2008+Part+5%3A+Mate%2c+the+Pure+MXML+Framework">FrameworkQuest 2008 Part 5: Mate, the Pure MXML Framework</a><br />
<a href="http://www.insideria.com/2009/01/frameworkquest-2008-part-6-the.html?CMP=AFC-ak_article&amp;ATT=FrameworkQuest+2008+Part+6%3A+The+Exciting+Conclusion">FrameworkQuest 2008 Part 6: The Exciting Conclusion</a>
</p></blockquote>
<p>Last week we took a look at how to clean up our Twitter client by<br />
using Cairngorm to separate the concerns according to the time honored MVC<br />
architectural pattern. Now we&#8217;re going to see how it feels to work with <a href="http://puremvc.org/"><span>PureMVC</span></a>, an<br />
ActionScript framework that wants to make it easier to do just that.</p>
<p>PureMVC was created by <a href="http://puremvc.org/component/option,com_contact/Itemid,3/"><span>Cliff Hall</span></a>, and is maintained in a few<br />
different forms by a <a href="http://puremvc.org/content/view/51/1/"><span>community of developers</span></a>.</p>
<p>Notice that PureMVC is an ActionScript framework. More<br />
specifically, there is an ActionScript 2 and two ActionScript 3 versions of<br />
PureMVC, one regular and one multi-core, which can work with Flex with Modules<br />
for instance. That&#8217;s one thing that PureMVC makes clear is that it has no<br />
dependencies on the Flex Framework, which means that it&#8217;s flexible enough to<br />
work with Flash projects as well as Flex. In fact PureMVC also has ports in the<br />
works or already developed for Java, C#, ColdFusion, Ruby, and others, so it<br />
tries to be a language independent take on an MVC framework.</p>
<p>Being framework independent means that unlike Cairngorm, PureMVC<br />
doesn&#8217;t rely on Flex binding. Not only that, but PureMVC wants to make sure<br />
that framework code doesn&#8217;t make it outside any of the classes that aren&#8217;t<br />
clearly framework oriented. This certainly applies to view classes, so PureMVC<br />
uses Flash events instead of a framework specific event type. This encourages<br />
the development of views as black box components, which encourages a loosely<br />
coupled architecture (which is also possible with Cairngorm) as well as a<br />
framework independent view (which is not, strictly speaking, possible with<br />
Cairngorm).</p>
<p>A little bit about the framework. PureMVC has a <span class="Code"><span>Controller</span></span>, a <span class="Code"><span>Model</span></span>, and a <span class="Code"><span>Facade</span></span>, all singletons.<span>&nbsp; </span>The <span class="Code"><span>Controller</span></span> has an API for sending and<br />
receiving <span class="Code"><span>Notifications</span></span>,<br />
which are event-like messages that any PureMVC object, except, by convention, <span class="Code"><span>Proxies</span></span>, can<br />
subscribe to. <span class="Code"><span>Proxies</span></span></p>
<p>never receive, they only send, <span class="Code"><span>Notifications</span></span>.<br />
The <span class="Code"><span>Model</span></span> keeps<br />
a set of named <span class="Code"><span>Proxy</span></span><br />
objects, which are responsible for a particular type of data in the model. For<br />
instance an application that has <span class="Code"><span>User</span></span> objects would probably have a <span class="Code"><span>UserProxy</span></span> that handled requests for<br />
users and managed a collection of users. The <span class="Code"><span>Model</span></span> and <span class="Code"><span>Controller</span></span> are unseen, and only<br />
accessed through the <span class="Code"><span>Facade</span></span>.<br />
The <span class="Code"><span>Facade</span></span> has<br />
an API for working with both the Model and Controller, sending <span class="Code"><span>Notifications</span></span>,<br />
looking up <span class="Code"><span>Proxies</span></span>,<br />
and so forth. Your application implements the <span class="Code"><span>Facade</span></span> class either by implementing<br />
the interface or extending a <span class="Code"><span>Facade</span></span></p>
<p>class that PureMVC provides. That brings up another point about PureMVC. Every<br />
part of PureMVC implements an interface, which is also provided so that you<br />
could replace any part of PureMVC with your own implementation if you wanted.</p>
<p>Let&#8217;s look at a flow of events in a PureMVC application.</p>
<p><img /></p>
<p>When a user interacts with the view, a Flash event is dispatched<br />
from the view. A <span class="Code"><span>Mediator</span></span><br />
responsible for that view has already registered for interesting events and<br />
when it receives this one, it may do view specific logic. Most likely, it will<br />
also send a <span class="Code"><span>Notification</span></span></p>
<p>which any other PureMVC objects may elect to receive. Keep that point in mind -<br />
that&#8217;s a very loosely coupled architecture. Any number of other <span class="Code"><span>Mediators</span></span> or <span class="Code"><span>Commands</span></span> can listen<br />
for a certain notification and do whatever it is they do.</p>
<p>The <span class="Code"><span>Controller</span></span><br />
is what gets called when a <span class="Code"><span>Notification</span></span></p>
<p>is sent, and it tells anyone interested in those types of <span class="Code"><span>Notifications</span></span> that they have some new<br />
mail. It&#8217;s also possible to register a <span class="Code"><span>Command</span></span> to a certain type of <span class="Code"><span>Notification</span></span>, and if one is found,<br />
it&#8217;s instantiated and executed. This is typically the case in service calls.<br />
The <span class="Code"><span>Command</span></span>&#8217;s<br />
job is then to get reference to a <span class="Code"><span>Proxy</span></span> through the <span class="Code"><span>Facade</span></span> and ask it to take some<br />
appropriate action. The <span class="Code"><span>Proxy</span></span></p>
<p>can either interact directly with some service if necessary, or as is sometimes<br />
done, a Cairngorm-style <span class="Code"><span>BusinessDelegate</span></span><br />
can be invoked instead. PureMVC is flexible on this point, and some developers<br />
find it desirable to have this service encapsulation for the same reasons as we<br />
already described last time &#8211; it helps cushion the application from change.</p>
<p>Once the service returns to the <span class="Code"><span>Proxy</span></span> directly or through a <span class="Code"><span>Delegate</span></span>, it sends a <span class="Code"><span>Notification</span></span>, which a<br />
<span class="Code"><span>Mediator</span></span> or<br />
another <span class="Code"><span>Command</span></span></p>
<p>can receive. If the <span class="Code"><span>Mediator</span></span><br />
listens for that <span class="Code"><span>Notification</span></span>,<br />
it&#8217;s because something needs to change on the view in response to the new state<br />
of the data in the <span class="Code"><span>Proxy</span></span>,<br />
and the <span class="Code"><span>Mediator</span></span><br />
is responsible for changing the view. It may do this by wiring data in a data<br />
provider directly to a property on the <span class="Code"><span>Proxy</span></span>.</p>
<p>So, a few differences from what we&#8217;ve seen with Cairngorm are:</p>
</p>
<p>1.<span>&nbsp;&nbsp;&nbsp; </span>No<br />
framework code in the views.</p>
</p>
<p>2.<span>&nbsp;&nbsp;&nbsp; </span>No<br />
singleton model, instead a set of <span class="Code"><span>Proxies</span></span></p>
</p>
<p>3.<span>&nbsp;&nbsp;&nbsp; </span>No<br />
Flex Binding, instead all views are encapsulated from the framework by <span class="Code"><span>Mediators</span></span>.</p>
<p>Now that we&#8217;ve heard the dry details, let&#8217;s take a tour of our<br />
app.</p>
<p class="Sub-heading">PureMVC TwitteRIA</p>
<p>As mentioned, most PureMVC actions go through the <span class="Code"><span>Facade</span></span> we created, <span class="Code"><span>ApplicationFacade</span></span> in<br />
this case, and most access to the <span class="Code"><span>Facade</span></span> is through helper methods on <span class="Code"><span>Mediator</span></span>, <span class="Code"><span>Proxy</span></span>, or <span class="Code"><span>Command</span></span>. One time you&#8217;ll probably act<br />
directly on the <span class="Code"><span>Facade</span></span></p>
<p>instance is at application startup, like we do here:</p>
<p><b>twitteria_puremvc/src/twitteria_puremvc.mxml #8, 16</b></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
creationComplete=&quot;&lt;span class=&quot;quote&quot;&gt;facade.startup(this)&lt;/span&gt;&quot;<br />
...<br />
&lt;span class=&quot;category1&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;var&lt;/span&gt; facade:ApplicationFacade =<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ApplicationFacade.getInstance();&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>We get a reference to the instance of the <span class="Code"><span>Facade</span></span> and call <span class="Code"><span>startup</span></span>, passing the instance of the<br />
  view, when the application is complete. Let&#8217;s go through the startup phase and<br />
see what happens there. </p>
<p><b>twitteria_puremvc/src/com/insideria/twitteria/ApplicationFacade.as<br />
#23-30</b></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
override protected &lt;span class=&quot;category1&quot;&gt;function&lt;/span&gt; initializeController():&lt;span class=&quot;category1&quot;&gt;void&lt;/span&gt; {<br />
&nbsp; &nbsp; &nbsp;&lt;span class=&quot;category1&quot;&gt;super&lt;/span&gt;.initializeController();<br />
&nbsp; &nbsp; &nbsp;registerCommand(STARTUP, &nbsp; &nbsp; &nbsp; &nbsp;StartupCommand);<br />
&nbsp; &nbsp; &nbsp;registerCommand(LOG_IN, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;LogInCommand);<br />
&nbsp; &nbsp; &nbsp;registerCommand(SET_STATUS, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;SetStatusCommand);<br />
&nbsp; &nbsp; &nbsp;registerCommand(LOAD_TIMELINE, &nbsp;LoadTimelineCommand);<br />
}&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>First of all, when <span class="Code"><span>ApplicationFacade</span></span> is first instantiated, <span class="Code"><span>initializeController</span></span></p>
<p>is called by the framework. Here we register commands to string constants.<br />
Later on, when we send <span class="Code"><span>Notifications</span></span><br />
created with these strings, the commands will be created and executed. For<br />
instance, here&#8217;s the one for <span class="Code"><span>STARTUP</span></span>.</p>
<p><b>twitteria_puremvc/src/com/insideria/twitteria/ApplicationFacade.as<br />
#10</b></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
<br />
&lt;span class=&quot;category1&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;static&lt;/span&gt; const STARTUP:&lt;span class=&quot;category2&quot;&gt;String&lt;/span&gt; = &quot;&lt;span class=&quot;quote&quot;&gt;startup&lt;/span&gt;&quot;;&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>And now when we call <span class="Code"><span>startup</span></span> we send a notification with the <span class="Code"><span>STARTUP</span></span> string, which will cause a <span class="Code"><span>StartupCommand</span></span> to be<br />
executed. When we send the notification we also send along a reference to the<br />
application.<span class="Code"><span></span></span></p>
<p><b>twitteria_puremvc/src/com/insideria/twitteria/ApplicationFacade.as<br />
#31-33</b></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
&lt;span class=&quot;category1&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;function&lt;/span&gt; startup(app:twitteria_puremvc):&lt;span class=&quot;category1&quot;&gt;void&lt;/span&gt; {<br />
&nbsp; &nbsp; &nbsp; sendNotification(STARTUP, app);<br />
}&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p><span class="Code"><span>StartupCommand</span></span><br />
is a <span class="Code"><span>MacroCommand</span></span>,<br />
which means it executes a set of sub-commands which we add in the framework<br />
called <span>initializeMacroCommand</span>.</p>
<p><b>twitteria_puremvc/src/com/insideria/twitteria/controller/StartupCommand.as<br />
#5-10</b></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
&lt;span class=&quot;category1&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;class&lt;/span&gt; StartupCommand &lt;span class=&quot;category1&quot;&gt;extends&lt;/span&gt; MacroCommand {<br />
&nbsp; &nbsp; &nbsp;override protected &lt;span class=&quot;category1&quot;&gt;function&lt;/span&gt; initializeMacroCommand():&lt;span class=&quot;category1&quot;&gt;void&lt;/span&gt; {<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; addSubCommand(ModelPrepCommand);<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; addSubCommand(ViewPrepCommand);<br />
&nbsp; &nbsp; &nbsp; }<br />
}&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>The <span class="Code"><span>ModelPrepCommand</span></span><br />
sets up the model:</p>
<p><b>twitteria_puremvc/src/com/insideria/twitteria/controller/ModelPrepCommand.as<br />
#9-16</b></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
<br />
&lt;span class=&quot;category1&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;class&lt;/span&gt; ModelPrepCommand &lt;span class=&quot;category1&quot;&gt;extends&lt;/span&gt; SimpleCommand {<br />
&nbsp; &nbsp; &nbsp; override &lt;span class=&quot;category1&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;function&lt;/span&gt; execute(note:INotification):&lt;span class=&quot;category1&quot;&gt;void&lt;/span&gt; {<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; facade.&lt;span class=&quot;category2&quot;&gt;registerProxy&lt;/span&gt;(&lt;span class=&quot;category1&quot;&gt;new&lt;/span&gt; TimelineProxy());<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; facade.&lt;span class=&quot;category2&quot;&gt;registerProxy&lt;/span&gt;(&lt;span class=&quot;category1&quot;&gt;new&lt;/span&gt; StatusProxy());<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; facade.&lt;span class=&quot;category2&quot;&gt;registerProxy&lt;/span&gt;(&lt;span class=&quot;category1&quot;&gt;new&lt;/span&gt; UserProxy());<br />
&nbsp; &nbsp; &nbsp; &nbsp;}<br />
}&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>And the <span class="Code"><span>ViewPrepCommand</span></span><br />
sets up the <span class="Code"><span>Mediators</span></span><br />
that control the views.</p>
<p><b>twitteria_puremvc/src/com/insideria/twitteria/controller/ViewPrepCommand.as<br />
#12-18</b></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
&lt;span class=&quot;category1&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;class&lt;/span&gt; ViewPrepCommand &lt;span class=&quot;category1&quot;&gt;extends&lt;/span&gt; SimpleCommand {<br />
&nbsp; &nbsp; &nbsp; override &lt;span class=&quot;category1&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;function&lt;/span&gt; execute(note:INotification):&lt;span class=&quot;category1&quot;&gt;void&lt;/span&gt; {<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;span class=&quot;category1&quot;&gt;var&lt;/span&gt; app:twitteria_puremvc = note.getBody()<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;as twitteria_puremvc;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; facade.registerMediator(<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;span class=&quot;category1&quot;&gt;new&lt;/span&gt; ApplicationMediator(app)<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; );<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; facade.registerMediator(<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;span class=&quot;category1&quot;&gt;new&lt;/span&gt; LoginViewMediator(app.loginView)<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; );<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; facade.registerMediator(<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;span class=&quot;category1&quot;&gt;new&lt;/span&gt; MainViewMediator(app.mainView)<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; );<br />
&nbsp; &nbsp; &nbsp; &nbsp;}<br />
}&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>Let&#8217;s analyze those two commands. First of all, note that they<br />
both extend <span class="Code"><span>SimpleCommand</span></span>.<br />
Doing that gives them access through the <span class="Code"><span>ApplicationFacade</span></span> singleton, which is<br />
registered by the framework and provided to all framework classes. That lets<br />
the commands register proxies and mediators easily. Registering those guys lets<br />
anyone with access to the facade get a reference by name. We&#8217;ll look at that in<br />
a bit.</p>
<p>One more thing to note is how we get the <span class="Code"><span>STARTUP</span></span> notification passed to each<br />
sub-command. Since we attached the reference to the application to the note, we<br />
can grab that off the body and get a reference to the view items that each <span class="Code"><span>Mediator</span></span> needs to<br />
mediate.</p>
<p>Whew! That was a lot, and it all took place before the user even<br />
sees the view. Now that<span>&nbsp; </span>all that<br />
is in place we can finally look at logging in.</p>
<p class="Sub-heading">Logging In</p>
<p>One other big difference in the root application from the Cairngorm<br />
version is an omission on the <span class="Code"><span>ViewStack</span></span>.</p>
<p><b>twitteria_puremvc/src/twitteria_puremvc.mxml #26</b></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
&amp;lt;mx:ViewStack id=&quot;&lt;span class=&quot;quote&quot;&gt;mainViewStack&lt;/span&gt;&quot; bottom=&quot;&lt;span class=&quot;quote&quot;&gt;0&lt;/span&gt;&quot; left=&quot;&lt;span class=&quot;quote&quot;&gt;0&lt;/span&gt;&quot; right=&quot;&lt;span class=&quot;quote&quot;&gt;0&lt;/span&gt;&quot; top=&quot;&lt;span class=&quot;quote&quot;&gt;30&lt;/span&gt;&quot;&amp;gt;&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>There&#8217;s no binding to tell the stack which child to show. To see<br />
where the <span class="Code"><span>ViewStack</span></span><br />
is actually controlled, we look at the <span class="Code"><span>ApplicationMediator</span></span>. When the Mediator is created in the <span class="Code"><span>ViewPrepCommand</span></span> and<br />
passed the application instance, the constructor keeps that reference.</p>
<p><b>twitteria_puremvc/src/com/insideria/twitteria/view/ApplicationMediator.as<br />
#15-17</b></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
&lt;span class=&quot;category1&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;function&lt;/span&gt; ApplicationMediator(viewComponent:twitteria_puremvc) {<br />
&nbsp; &nbsp; &nbsp;&lt;span class=&quot;category1&quot;&gt;super&lt;/span&gt;(NAME, viewComponent);<br />
}&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>Passing the app reference along with the <span class="Code"><span>NAME</span></span> constant sets the <span class="Code"><span>viewComponent</span></span><br />
property for this mediator and also registers with the <span class="Code"><span>Facade</span></span> using <span class="Code"><span>NAME</span></span>, which is an arbitrary string:</p>
<p><b>twitteria_puremvc/src/com/insideria/twitteria/view/ApplicationMediator.as<br />
#10</b></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
&lt;span class=&quot;category1&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;static&lt;/span&gt; const NAME:&lt;span class=&quot;category2&quot;&gt;String&lt;/span&gt; = &quot;&lt;span class=&quot;quote&quot;&gt;ApplicationMediator&lt;/span&gt;&quot;;&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>Using that string lets anyone look the mediator up by that name.<br />
It&#8217;s also usual to set up a little helper lookup to bring back the <span class="Code"><span>viewComponent</span></span> as a<br />
typed object of the type we know it to be:</p>
<p><b>twitteria_puremvc/src/com/insideria/twitteria/view/ApplicationMediator.as<br />
#33-35</b></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
protected &lt;span class=&quot;category1&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;category2&quot;&gt;get&lt;/span&gt; app():twitteria_puremvc {<br />
&nbsp; &nbsp; &nbsp;&lt;span class=&quot;category1&quot;&gt;return&lt;/span&gt; viewComponent as twitteria_puremvc<br />
}&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>When the <span class="Code"><span>ApplicationMediator</span></span><br />
is registered, a framework method is called to set up the mediator.</p>
<p><b>twitteria_puremvc/src/com/insideria/twitteria/view/ApplicationMediator.as<br />
#33-35</b></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
<br />
override &lt;span class=&quot;category1&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;function&lt;/span&gt; listNotificationInterests():&lt;span class=&quot;category2&quot;&gt;Array&lt;/span&gt; {<br />
&nbsp; &nbsp; &nbsp;&lt;span class=&quot;category1&quot;&gt;return&lt;/span&gt; [<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ApplicationFacade.VIEW_TIMELINE<br />
&nbsp; &nbsp; &nbsp; ];<br />
}&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>One method the framework calls is <span>listNotificationInterests</span>. This should return a list<br />
of strings that the mediator is interested in receiving. Then, whenever any<br />
notification with those types are sent through the facade, this mediator will<br />
get notified. Notification happens when the framework calls <span>handleNotification</span>.<span></span></p>
<p class="MsoNormal"><span>&nbsp;</span></p>
<p><b>twitteria_puremvc/src/com/insideria/twitteria/view/ApplicationMediator.as<br />
#25-31</b></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
override &lt;span class=&quot;category1&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;function&lt;/span&gt; handleNotification(note:INotification):&lt;span class=&quot;category1&quot;&gt;void&lt;/span&gt; {<br />
&nbsp; &nbsp; &nbsp;&lt;span class=&quot;category1&quot;&gt;switch&lt;/span&gt; (note.getName()) {<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;span class=&quot;category1&quot;&gt;case&lt;/span&gt; ApplicationFacade.VIEW_TIMELINE:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;app.mainViewStack.selectedIndex = MAIN_VIEW;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;span class=&quot;category1&quot;&gt;break&lt;/span&gt;;<br />
&nbsp; &nbsp; &nbsp; }<br />
}&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>This method gets called when any notification that the mediator<br />
is interested in gets sent. The usual process is to switch on the notification<br />
name and then do the right thing.<span>&nbsp;<br />
</span>In this case, when the <span class="Code"><span>VIEW_TIMELINE</span></span><br />
note comes through, we want to switch the <span class="Code"><span>ViewStack</span></span> index to the <span class="Code"><span>MAIN_VIEW</span></span> constant,<br />
which just like the Cairngorm implementation and just like the no-framework<br />
implementation, points to the right index to show <span class="Code"><span>MainView</span></span>. So that&#8217;s how the <span class="Code"><span>ApplicationMediator</span></span></p>
<p>does what it do, as they say. When does the <span class="Code"><span>VIEW_TIMELINE</span></span> notification get sent?<br />
Let&#8217;s look at the <span class="Code"><span>LoginView</span></span><br />
to see.</p>
<p><b>twitteria_puremvc/src/com/insideria/twitteria/view/components/LoginView.mxml<br />
#4-16</b></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
&amp;lt;mx:Metadata&amp;gt;<br />
&nbsp; &nbsp; &nbsp;[Event(&lt;span class=&quot;category2&quot;&gt;name&lt;/span&gt;=&quot;&lt;span class=&quot;quote&quot;&gt;login&lt;/span&gt;&quot;, &lt;span class=&quot;category2&quot;&gt;type&lt;/span&gt;=&quot;&lt;span class=&quot;quote&quot;&gt;flash.events.Event&lt;/span&gt;&quot;)]<br />
&amp;lt;/mx:Metadata&amp;gt;<br />
<br />
&amp;lt;mx:Script&amp;gt;<br />
<br />
&amp;lt;![CDATA[<br />
&nbsp; &nbsp; &nbsp;&lt;span class=&quot;category1&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;static&lt;/span&gt; const LOGIN:&lt;span class=&quot;category2&quot;&gt;String&lt;/span&gt; = '&lt;span class=&quot;quote&quot;&gt;login&lt;/span&gt;';<br />
<br />
&nbsp; &nbsp; &nbsp;&lt;span class=&quot;category1&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;function&lt;/span&gt; login():&lt;span class=&quot;category1&quot;&gt;void&lt;/span&gt; {<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dispatchEvent(&lt;span class=&quot;category1&quot;&gt;new&lt;/span&gt; Event(LOGIN));<br />
&nbsp; &nbsp; &nbsp; }<br />
]]&amp;gt;<br />
<br />
&amp;lt;/mx:Script&amp;gt;&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>The first thing you may notice is that we&#8217;re back to dispatching<br />
a regular Flash event when enter is pressed on the password field:</p>
<p><b>twitteria_puremvc/src/com/insideria/twitteria/view/components/LoginView.mxml<br />
#27</b></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
<br />
enter=&quot;&lt;span class=&quot;quote&quot;&gt;login()&lt;/span&gt;&quot;&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>Who&#8217;s listening? The <span class="Code"><span>LoginViewMediator</span></span>, which as also set up in the <span class="Code"><span>ViewPrepCommand</span></span>. When<br />
the mediator is created, it adds itself as an event listener for this type.</p>
<p><b>twitteria_puremvc/src/com/insideria/twitteria/view/LoginViewMediator.mxml<br />
#15-19</b></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
&lt;span class=&quot;category1&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;function&lt;/span&gt; LoginViewMediator(viewComponent:LoginView) {<br />
&nbsp; &nbsp; &nbsp;&lt;span class=&quot;category1&quot;&gt;super&lt;/span&gt;(NAME, viewComponent);<br />
<br />
&nbsp; &nbsp; &nbsp; view.addEventListener(LoginView.LOGIN, login);<br />
}&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>So when the view dispatches that event, the mediator&#8217;s login<br />
method will be called.</p>
<p><b>twitteria_puremvc/src/com/insideria/twitteria/view/LoginViewMediator.mxml<br />
#15-19</b></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
&lt;span class=&quot;category1&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;function&lt;/span&gt; login(event:Event):&lt;span class=&quot;category1&quot;&gt;void&lt;/span&gt; {<br />
&nbsp; &nbsp; &nbsp; &lt;span class=&quot;category1&quot;&gt;var&lt;/span&gt; credentials:&lt;span class=&quot;category2&quot;&gt;Object&lt;/span&gt; = {<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;username:view.usernameText.&lt;span class=&quot;category2&quot;&gt;text&lt;/span&gt;,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;span class=&quot;category2&quot;&gt;password&lt;/span&gt;:view.passwordText.&lt;span class=&quot;category2&quot;&gt;text&lt;/span&gt;<br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp;};<br />
&nbsp; &nbsp; &nbsp; sendNotification(ApplicationFacade.LOG_IN, credentials);<br />
}&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>The login method gets a little ad-hoc object together and sends<br />
it along with a notification. We could change that to be a typed object, but<br />
for now a hash is good enough. The note name is in the <span class="Code"><span>LOG_IN</span></span> variable on the facade, and if<br />
you&#8217;ll remember, that was registered to the <span class="Code"><span>LoginCommand</span></span>. </p>
<p><b>twitteria_puremvc/src/com/insideria/twitteria/controller/LoginCommand.as<br />
#11-19</b></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
override &lt;span class=&quot;category1&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;function&lt;/span&gt; execute(note:INotification):&lt;span class=&quot;category1&quot;&gt;void&lt;/span&gt; {<br />
&nbsp; &nbsp; &nbsp; &lt;span class=&quot;category1&quot;&gt;var&lt;/span&gt; userProxy:UserProxy =<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;facade.retrieveProxy(UserProxy.NAME) as UserProxy;<br />
&nbsp; &nbsp; &nbsp; &lt;span class=&quot;category1&quot;&gt;var&lt;/span&gt; timelineProxy:TimelineProxy =<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;facade.retrieveProxy(TimelineProxy.NAME) as TimelineProxy;<br />
&nbsp; &nbsp; &nbsp; &lt;span class=&quot;category1&quot;&gt;var&lt;/span&gt; credentials:&lt;span class=&quot;category2&quot;&gt;Object&lt;/span&gt; = note.getBody();<br />
<br />
&nbsp; &nbsp; &nbsp; userProxy.username = credentials['&lt;span class=&quot;quote&quot;&gt;username&lt;/span&gt;'];<br />
&nbsp; &nbsp; &nbsp; userProxy.&lt;span class=&quot;category2&quot;&gt;password&lt;/span&gt; = credentials['&lt;span class=&quot;quote&quot;&gt;password&lt;/span&gt;'];<br />
&nbsp; &nbsp; &nbsp; sendNotification(ApplicationFacade.LOAD_TIMELINE);<br />
}&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>The <span class="Code"><span>UserProxy</span></span><br />
simply stores the username and password; have a look at it if you want. With a<br />
more complex login process it would get a little more complex too, but that&#8217;s<br />
enough for here. Again, notice that the username/password hash is on the body<br />
of the <span class="Code"><span>Notification</span></span>.<br />
At the end of the command, we send out another notification, signaling that<br />
log-in is complete and it&#8217;s time to load the timeline.</p>
<p class="Sub-heading">Loading The Timeline</p>
<p>To load the timeline, we call on the <span class="Code"><span>TimelineProxy</span></span> in the <span class="Code"><span>LoadTimelineCommand</span></span>, which was<br />
registered to the <span class="Code"><span>LOAD_TIMELINE</span></span><br />
notification type.</p>
<p><b>twitteria_puremvc/src/com/insideria/twitteria/controller/LoadTimelineCommand.as<br />
#10-13</b></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
override &lt;span class=&quot;category1&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;function&lt;/span&gt; execute(note:INotification):&lt;span class=&quot;category1&quot;&gt;void&lt;/span&gt; {<br />
&nbsp; &nbsp; &nbsp; &lt;span class=&quot;category1&quot;&gt;var&lt;/span&gt; timelineProxy:TimelineProxy =<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;facade.retrieveProxy(TimelineProxy.NAME) as TimelineProxy;<br />
&nbsp; &nbsp; &nbsp; timelineProxy.reload();<br />
}&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>The <span class="Code"><span>reload</span></span><br />
method goes like this:</p>
<p><b>twitteria_puremvc/src/com/insideria/twitteria/model/TimelineProxy.as<br />
#22-25</b></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
&lt;span class=&quot;category1&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;function&lt;/span&gt; reload():&lt;span class=&quot;category1&quot;&gt;void&lt;/span&gt; {<br />
&nbsp; &nbsp; &nbsp; &lt;span class=&quot;category1&quot;&gt;var&lt;/span&gt; delegate:TwitterDelegate = &lt;span class=&quot;category1&quot;&gt;new&lt;/span&gt; TwitterDelegate(&lt;span class=&quot;category1&quot;&gt;this&lt;/span&gt;);<br />
&nbsp; &nbsp; &nbsp; delegate.loadTimeline();<br />
}&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>Notice that the <span class="Code"><span>TimelineProxy</span></span><br />
implements <span class="Code"><span>IResponder</span></span>,<br />
and that I&#8217;ve chosen to use the Business Delegate pattern. Nothing from here to<br />
the service changed from the Cairngorm implementation except that it&#8217;s a <span class="Code"><span>Proxy</span></span> instead of a <span class="Code"><span>Command</span></span> calling the<br />
delegate. These choices aren&#8217;t mandated by PureMVC, but it&#8217;s flexible enough to<br />
allow this way of doing things. I&#8217;m not sure I like the <span class="Code"><span>Proxy</span></span> being an <span class="Code"><span>IResponder</span></span> because that limits it to<br />
only one set of <span class="Code"><span>result</span></span>/<span class="Code"><span>fault</span></span> methods and<br />
only one call on the delegate. That could be changed to a more flexible event<br />
listener approach, but for now I chose to keep things pretty similar to how<br />
they were.</p>
<p><b>twitteria_puremvc/src/com/insideria/twitteria/model/TimelineProxy.as<br />
#27-32</b></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
&lt;span class=&quot;category1&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;function&lt;/span&gt; result(result:&lt;span class=&quot;category2&quot;&gt;Object&lt;/span&gt;):&lt;span class=&quot;category1&quot;&gt;void&lt;/span&gt; {<br />
&nbsp; &nbsp; &nbsp; &lt;span class=&quot;category1&quot;&gt;var&lt;/span&gt; stati:&lt;span class=&quot;category2&quot;&gt;Array&lt;/span&gt; = result as &lt;span class=&quot;category2&quot;&gt;Array&lt;/span&gt;;<br />
&nbsp; &nbsp; &nbsp; currentTweets = &lt;span class=&quot;category1&quot;&gt;new&lt;/span&gt; ArrayCollection(stati);<br />
&nbsp; &nbsp; &nbsp; sendNotification(ApplicationFacade.VIEW_TIMELINE);<br />
&nbsp; &nbsp; &nbsp; sendNotification(ApplicationFacade.TIMELINE_LOADED);<br />
}&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>When the delegate returns to the result method, we fire off two<br />
notifications: <span class="Code"><span>VIEW_TIMELINE</span></span><br />
and <span class="Code"><span>TIMELINE_LOADED</span></span>.<br />
Why two? One lets the application know to change view states, and the other<br />
lets the application know that there&#8217;s new data in the <span class="Code"><span>TimelineProxy</span></span>. Those may happen<br />
concurrently here, but they don&#8217;t always have to. If you remember back a bit, <span class="Code"><span>VIEW_TIMELINE</span></span> was a<br />
notification that the <span class="Code"><span>ApplicationMediator</span></span></p>
<p>was interested in. When this notification makes it there, that mediator<br />
switches the index in the <span class="Code"><span>ViewStack</span></span><br />
to show the <span class="Code"><span>MainView</span></span>,<br />
as you saw above. Who&#8217;s interested in the <span class="Code"><span>TIMELINE_LOADED</span></span> notification? That<br />
would be the <span class="Code"><span>MainViewMediator</span></span>.</p>
<p><b>twitteria_puremvc/src/com/insideria/twitteria/view/MainViewMediator.mxml<br />
#33-39</b></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
override &lt;span class=&quot;category1&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;function&lt;/span&gt; handleNotification(note:INotification):&lt;span class=&quot;category1&quot;&gt;void&lt;/span&gt; {<br />
&nbsp; &nbsp; &nbsp;&lt;span class=&quot;category1&quot;&gt;switch&lt;/span&gt; (note.getName()) {<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;span class=&quot;category1&quot;&gt;case&lt;/span&gt; ApplicationFacade.TIMELINE_LOADED:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;view.currentTweets = getTimelineProxy().currentTweets;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;span class=&quot;category1&quot;&gt;break&lt;/span&gt;;<br />
&nbsp; &nbsp; &nbsp; }<br />
}&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>When the <span class="Code"><span>MainViewMediator</span></span><br />
gets the <span class="Code"><span>TIMELINE_LOADED</span></span><br />
note, it sets the <span class="Code"><span>currentTweets</span></span><br />
property to the <span class="Code"><span>TimelineProxy</span></span>&#8217;s<br />
<span class="Code"><span>currentTweets</span></span>.<br />
This is how the framework gets around binding the view to the model &#8211; the<br />
mediator hooks the properties on a proxy directly to the view.</p>
<p>Now the view is on the <span class="Code"><span>MainView</span></span> and the tweets are loaded into the list. It&#8217;s<br />
time to set the status.</p>
<p class="Sub-heading">Setting Status</p>
<p>Just as the <span class="Code"><span>LoginView</span></span></p>
<p>dispatches a plain-old-flash-event when you hit enter, the <span class="Code"><span>MainView</span></span> dispatches an event when the<br />
status is set by pressing enter in the status field</p>
<p><b>twitteria_puremvc/src/com/insideria/twitteria/view/components/MainView.mxml<br />
#4-23</b></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
&amp;lt;mx:Metadata&amp;gt;<br />
&nbsp; &nbsp; &nbsp;[Event(&lt;span class=&quot;category2&quot;&gt;name&lt;/span&gt;=&quot;&lt;span class=&quot;quote&quot;&gt;setStatus&lt;/span&gt;&quot;, &lt;span class=&quot;category2&quot;&gt;type&lt;/span&gt;=&quot;&lt;span class=&quot;quote&quot;&gt;flash.events.Event&lt;/span&gt;&quot;)]<br />
<br />
&amp;lt;/mx:Metadata&amp;gt;<br />
<br />
&amp;lt;mx:Script&amp;gt;<br />
&amp;lt;![CDATA[<br />
&nbsp; &nbsp; &nbsp;&lt;span class=&quot;category1&quot;&gt;import&lt;/span&gt; mx.collections.ArrayCollection;<br />
<br />
&nbsp; &nbsp; &nbsp;&lt;span class=&quot;category1&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;static&lt;/span&gt; const SET_STATUS:&lt;span class=&quot;category2&quot;&gt;String&lt;/span&gt; = '&lt;span class=&quot;quote&quot;&gt;setStatus&lt;/span&gt;';<br />
<br />
&nbsp; &nbsp; &nbsp;[Bindable]<br />
&nbsp; &nbsp; &nbsp;&lt;span class=&quot;category1&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;var&lt;/span&gt; currentTweets:ArrayCollection; &lt;span class=&quot;linecomment&quot;&gt;// &amp;lt;TwitterStatus&amp;gt;&lt;/span&gt;<br />
<br />
&nbsp; &nbsp; &nbsp;&lt;span class=&quot;category1&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;function&lt;/span&gt; setStatus():&lt;span class=&quot;category1&quot;&gt;void&lt;/span&gt; {<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dispatchEvent(&lt;span class=&quot;category1&quot;&gt;new&lt;/span&gt; Event(SET_STATUS));<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;statusText.&lt;span class=&quot;category2&quot;&gt;clear&lt;/span&gt;();<br />
&nbsp; &nbsp; &nbsp; }<br />
]]&amp;gt;<br />
&amp;lt;/mx:Script&amp;gt;&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>The <span class="Code"><span>MainViewMediator</span></span><br />
  has an event listener, <span class="Code"><span>setStatus</span></span>,<br />
that handles that event.</p>
<p><b>twitteria_puremvc/src/com/insideria/twitteria/view/MainViewMediator.mxml<br />
#41-43 (formatted)</b></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
&lt;span class=&quot;category1&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;function&lt;/span&gt; setStatus(event:Event):&lt;span class=&quot;category1&quot;&gt;void&lt;/span&gt; {<br />
&nbsp; &nbsp; &nbsp; sendNotification(<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ApplicationFacade.SET_STATUS,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;view.statusText.&lt;span class=&quot;category2&quot;&gt;text&lt;/span&gt;<br />
&nbsp; &nbsp; &nbsp; );<br />
}&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>The <span class="Code"><span>SET_STATUS</span></span><br />
notification corresponds to the <span class="Code"><span>SetStatusCommand</span></span>.</p>
<p class="MsoNormal"><b>twitteria_puremvc/src/com/insideria/twitteria/controller/SetStatusCommand.as<br />
#10-13 (formatted)</b></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
override &lt;span class=&quot;category1&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;function&lt;/span&gt; execute(note:INotification):&lt;span class=&quot;category1&quot;&gt;void&lt;/span&gt; {<br />
&nbsp; &nbsp; &nbsp; &lt;span class=&quot;category1&quot;&gt;var&lt;/span&gt; statusProxy:StatusProxy =<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;facade.retrieveProxy(StatusProxy.NAME) as StatusProxy;<br />
&nbsp; &nbsp; &nbsp; statusProxy.setStatus(note.getBody() as &lt;span class=&quot;category2&quot;&gt;String&lt;/span&gt;);<br />
}&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>The <span class="Code"><span>StatusProxy</span></span><br />
calls out to the <span class="Code"><span>TwitterDelegate</span></span><br />
just like the Cairngorm <span class="Code"><span>SetStatusCommand</span></span><br />
used to.</p>
<p class="MsoNormal"><b>twitteria_puremvc/src/com/insideria/twitteria/model/StatusProxy.as<br />
#19-22</b></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
&lt;span class=&quot;category1&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;function&lt;/span&gt; setStatus(statusText:&lt;span class=&quot;category2&quot;&gt;String&lt;/span&gt;):&lt;span class=&quot;category1&quot;&gt;void&lt;/span&gt; {<br />
&nbsp; &nbsp; &nbsp; &lt;span class=&quot;category1&quot;&gt;var&lt;/span&gt; delegate:TwitterDelegate = &lt;span class=&quot;category1&quot;&gt;new&lt;/span&gt; TwitterDelegate(&lt;span class=&quot;category1&quot;&gt;this&lt;/span&gt;);<br />
&nbsp; &nbsp; &nbsp; delegate.setStatus(statusText);<br />
}&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>And when the result comes back, it sends out just the <span class="Code"><span>LOAD_TIMELINE</span></span><br />
notification, which as we saw above, kicks off the timeline load sequence.</p>
<p class="MsoNormal"><b>twitteria_puremvc/src/com/insideria/twitteria/model/StatusProxy.as<br />
#24-26</b></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
<br />
&lt;span class=&quot;category1&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;function&lt;/span&gt; result(result:&lt;span class=&quot;category2&quot;&gt;Object&lt;/span&gt;):&lt;span class=&quot;category1&quot;&gt;void&lt;/span&gt; {<br />
&nbsp; &nbsp; &nbsp; sendNotification(ApplicationFacade.LOAD_TIMELINE);<br />
}&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>Play around with the application, in dummy data mode and out.<br />
Kick it around and see if you can think of anything to add. There are a lot of<br />
moving parts to PureMVC, so think through the flows a bit again, just to make<br />
sure you have an idea of what each piece does.</p>
<p class="Sub-heading">Next Up</p>
<p>Well folks, that&#8217;s PureMVC. Some key parts again are that nothing<br />
from the framework enters the view components (except once, in the root<br />
application), the model is broken up into many <span class="Code"><span>Proxies</span></span>, views that need framework action<br />
are acted upon by <span class="Code"><span>Mediators</span></span>,<br />
<span class="Code"><span>Commands</span></span><br />
generally tell a <span class="Code"><span>Proxy</span></span><br />
to do something, and communication between all the parts is done through <span class="Code"><span>Notifications</span></span>.</p>
<p>It may strike you that you have to do a lot by hand to get<br />
everything working together with PureMVC. If you&#8217;d like your framework to take<br />
a little bit more initiative for you, then you might want to see what the Swiz<br />
way of doing things looks like. That&#8217;s just what we&#8217;re going to do next time,<br />
so watch this space! <span></span></p>
<p><a href="http://www.insideria.com/tony-hillerson/">Read more from<br />
Tony Hillerson</a>.</p>


<p>Related posts:<ol><li><a href='http://flex.exposedout.net/2009/01/16/frameworkquest-2008-part-5-mate-the-pure-mxml-framework/' rel='bookmark' title='Permanent Link: FrameworkQuest 2008 Part 5: Mate, the Pure MXML Framework'>FrameworkQuest 2008 Part 5: Mate, the Pure MXML Framework</a></li>
<li><a href='http://flex.exposedout.net/2009/01/16/frameworkquest-2008-part-6-the-exciting-conclusion/' rel='bookmark' title='Permanent Link: FrameworkQuest 2008 Part 6: The Exciting Conclusion'>FrameworkQuest 2008 Part 6: The Exciting Conclusion</a></li>
<li><a href='http://flex.exposedout.net/2009/01/16/frameworkquest-2008-part-4-ioc-with-swiz/' rel='bookmark' title='Permanent Link: FrameworkQuest 2008 Part 4: IoC With Swiz'>FrameworkQuest 2008 Part 4: IoC With Swiz</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://flex.exposedout.net/2009/01/16/frameworkquest-2008-part-3-framework-agnostic-views-with-puremvc/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>FrameworkQuest 2008 Part 2: Get Control with Cairngorm</title>
		<link>http://flex.exposedout.net/2009/01/16/frameworkquest-2008-part-2-get-control-with-cairngorm/</link>
		<comments>http://flex.exposedout.net/2009/01/16/frameworkquest-2008-part-2-get-control-with-cairngorm/#comments</comments>
		<pubDate>Fri, 16 Jan 2009 10:45:53 +0000</pubDate>
		<dc:creator>Vikram singh</dc:creator>
				<category><![CDATA[flex]]></category>
		<category><![CDATA[framework]]></category>

		<guid isPermaLink="false">http://guavus.wordpress.com/?p=157</guid>
		<description><![CDATA[FrameworkQuest Part 2 by Tony Hillerson Find the original post here print listen FrameworkQuest 2008: Introduction FrameworkQuest 2008 Part 2: Get Control with Cairngorm FrameworkQuest 2008 Part 3: Agnostic Views with PureMVC FrameworkQuest 2008 Part 4: IoC With Swiz FrameworkQuest 2008 Part 5: Mate, the Pure MXML Framework FrameworkQuest 2008 Part 6: The Exciting Conclusion [...]


Related posts:<ol><li><a href='http://flex.exposedout.net/2009/01/16/frameworkquest-2008-part-4-ioc-with-swiz/' rel='bookmark' title='Permanent Link: FrameworkQuest 2008 Part 4: IoC With Swiz'>FrameworkQuest 2008 Part 4: IoC With Swiz</a></li>
<li><a href='http://flex.exposedout.net/2009/01/16/frameworkquest-2008-part-3-framework-agnostic-views-with-puremvc/' rel='bookmark' title='Permanent Link: FrameworkQuest 2008 Part 3: Framework Agnostic Views with PureMVC'>FrameworkQuest 2008 Part 3: Framework Agnostic Views with PureMVC</a></li>
<li><a href='http://flex.exposedout.net/2009/01/16/frameworkquest-2008-part-5-mate-the-pure-mxml-framework/' rel='bookmark' title='Permanent Link: FrameworkQuest 2008 Part 5: Mate, the Pure MXML Framework'>FrameworkQuest 2008 Part 5: Mate, the Pure MXML Framework</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>FrameworkQuest Part 2 by <strong>Tony Hillerson</strong><br />
Find the original post <a href="http://www.insideria.com/2008/12/frameworkquest-2008-part-2-get.html?CMP=AFC-ak_article&amp;ATT=FrameworkQuest+2008++Part+2%3A+Get+Control+with+Cairngorm">here</a></p>
<div class="button"><a href="http://www.insideria.com/print/33895.html" target="_blank">print <img src="http://insideria.com/riaimages/printtag.jpg" style="border:none;" /></a><br />
<a target="_new" href="http://asp2.readspeaker.net/cgi-bin/oreillyrsone?lang=us&amp;voice=Paul&amp;customerid=171&amp;url=http://www.insideria.com/2008/12/frameworkquest-2008-part-2-get.html">listen <img src="http://www.oreillynet.com/images/icon_listen_small.gif" width="10" height="9" alt="Speech Icon" /></a></div>
<blockquote><p>
<a href="http://www.insideria.com/2008/12/frameworkquest-2008-introducti.html">FrameworkQuest 2008: Introduction</a><br />
<a href="http://www.insideria.com/2008/12/frameworkquest-2008-part-2-get.html?CMP=AFC-ak_article&amp;ATT=FrameworkQuest+2008++Part+2%3A+Get+Control+with+Cairngorm">FrameworkQuest 2008 Part 2: Get Control with Cairngorm</a><br />
<a href="http://www.insideria.com/2008/12/frameworkquest-2008-part-3-fra.html?CMP=AFC-ak_article&amp;ATT=FrameworkQuest+2008+Part+3%3A+Framework+Agnostic+Views+with+PureMVC">FrameworkQuest 2008 Part 3: Agnostic Views with PureMVC</a><br />
<a href="http://www.insideria.com/2008/12/frameworkquest-2008-part-4-ioc.html?CMP=AFC-ak_article&amp;ATT=FrameworkQuest+2008+Part+4%3A+IoC+With+Swiz">FrameworkQuest 2008 Part 4: IoC With Swiz</a><br />
<a href="http://www.insideria.com/2008/12/frameworkquest-2008-part-5-mat.html?CMP=AFC-ak_article&amp;ATT=FrameworkQuest+2008+Part+5%3A+Mate%2c+the+Pure+MXML+Framework">FrameworkQuest 2008 Part 5: Mate, the Pure MXML Framework</a><br />
<a href="http://www.insideria.com/2009/01/frameworkquest-2008-part-6-the.html?CMP=AFC-ak_article&amp;ATT=FrameworkQuest+2008+Part+6%3A+The+Exciting+Conclusion">FrameworkQuest 2008 Part 6: The Exciting Conclusion</a>
</p></blockquote>
<p> <strong>Carebear? Carhorn? What?</strong></p>
<p><a href="http://opensource.adobe.com/wiki/display/cairngorm/Cairngorm" target="_blank">Cairngorm</a> is the Flex Framework with the odd name that&#8217;s been around almost since the beginning of Flex. It was created by a company called iteration::two, which went on to become Adobe Consulting&#8217;s European practice around the same time Adobe acquired Macromedia. These guys had been using Flex very early on, and were some of the first to talk about how important it was to building business applications. They even wrote <a href="http://www.amazon.com/Developing-Rich-Clients-Macromedia-Flex/dp/0321255666/" target="_blank">the first commercially available Flex book</a>, which helped to lend Cairngorm a lot of credibility when they released it soon after.</p>
<p>So what&#8217;s a Cairngorm? The <a href="http://en.wikipedia.org/wiki/Cairngorms">Cairngorms</a> are a mountain range in Scotland and <a href="http://en.wikipedia.org/wiki/Cairn_Gorm">Cairn Gorm</a> is one of the famous peaks in that range. It&#8217;s 4000 feet above sea level, which isn&#8217;t impressive on paper to a Colorado-an like me (we have 25 peaks over 14,000 feet, and 56 over 4000m, so nyah-nyah), but then again, we have a continent underneath us to prop things up a bit. I&#8217;d love to see the Cairngorms one day and I&#8217;m sure the highland beauty, if not the mass quantities of <a href="http://en.wikipedia.org/wiki/Lagavulin">Scotch Whisky</a>, would make a suitable impression. </p>
<p>So how do you pronounce it? Most people say &#8220;CAREn-gorm&#8221;, and some say &#8220;CARn-gorm&#8221; (for American English values of &#8220;care&#8221; and &#8220;car&#8221;). I have no idea, but I think the &#8220;car&#8221; version may be closer to the Scotch pronunciation.</p>
<p>If you&#8217;d like to learn more about Cairngorm, the <a href="http://opensource.adobe.com/wiki/display/cairngorm/Developer+Documentation">documentation is here</a>.</p>
<p>Now, back to Flex land, let&#8217;s see where we left off.</p>
<p><strong>Reviewing our Mess</strong></p>
<p>In the last episode of our series on Frameworks we looked at an AIR application created using Flex, but used no Flex framework. Here are a list of problems we hope to solve with a framework.</p>
<ol>
<li></li>
<li>1.    Poor Organization</li>
<li>2.    Unstructured Application State</li>
<li>3.    Bloated Views</li>
</ol>
<p><strong>MVC to the Rescue</strong></p>
<p>Many of you have heard of the concept of the Model/View/Controller architectural pattern. When we apply this pattern to an application, the code is separated into three general concerns &#8211; the Model, the View, and the Controller.</p>
<p>The Model is responsible for holding the state of the application, which means any information that the application could display, any information that the application needs to use to contact services, and any information about a particular session with a user, like where they are in the application. </p>
<p>The View is responsible for displaying the data in the model and informing the rest of the application about user interaction, such as the click of a button.</p>
<p>There are a few rules that MVC applies to the model and the view. One is that the model should not know about the view. That means that however the data gets from the model to the view, the model can&#8217;t be the one putting it there. Conversely, the view shouldn&#8217;t act directly on the model to change its state. Another rule is that the view shouldn&#8217;t know about the controller. It doesn&#8217;t have a reference to any part of the controller, so it can&#8217;t change anything about the controller directly.</p>
<p>That leaves The Controller to somehow respond to user interaction notifications from the view and inform the model appropriately, possibly changing the state of the model. Then through some mechanism that makes sense, the view is updated to reflect the new state of the model.</p>
<p>MVC was created to help keep business logic and view logic separate so that, theoretically, changes in the one don&#8217;t require changes in the other. The principles of MVC are going to show up in all the frameworks we discuss, so keep them in mind.</p>
<p>Now let&#8217;s look at how Cairngorm does things.</p>
<p><strong>Cairngorm: Dramatis Personae</strong></p>
<p>Cairngorm is described by Adobe Consulting as a microframework, or a set of patterns available to developers to assist in building an application. Here&#8217;s a normal flow of operations and the Cairngorm classes that are exercised.</p>
<p><img /></p>
<p>When the user takes some sort of action on the view, such as clicking a button, the view dispatches a <strong>CairngormEvent</strong>. This event informs the <strong>FrontController</strong>, which instantiates a <strong>Command</strong>. The command executes the business logic, and the event is responsible for passing data to the command about the user interaction.</p>
<p>The command can either take some action on the <strong>Model</strong>, or instantiate and act on a Business Delegate. The <strong>Business Delegate</strong>, or delegate for short, wraps the code required for a service call, so it acts like the service API to the rest of the application. This is important because when the service changes, the changes to the application can be minimized and ideally only the delegate needs to change. The delegate calls the service and then depending on the kind of service involved makes sure that the command is informed when the service call has returned. Then the command changes the state of the model, if necessary, and the model, through Flex&#8217;s binding, updates the view.</p>
<p>That was a whirlwind tour, but if we look at some code I think it will become a little clearer.</p>
<p><strong>TwitteRIA on Cairngorm</strong></p>
<p>First we&#8217;ll look at changes to the top-level application. The Script-block has changed to this:</p>
<p><strong>twitteria_cairngorm/src/twitteria_cairngorm.mxml #6-13</strong></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
&amp;lt;mx:Script&amp;gt;<br />
&amp;lt;![CDATA[<br />
&nbsp; &nbsp; &nbsp;&lt;span class=&quot;category1&quot;&gt;import&lt;/span&gt; com.insideria.twitteria.model.TwitteRIAModel;<br />
<br />
&nbsp; &nbsp; &nbsp;[Bindable]<br />
&nbsp; &nbsp; &nbsp;&lt;span class=&quot;category1&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;var&lt;/span&gt; model:TwitteRIAModel = TwitteRIAModel.getInstance();<br />
]]&amp;gt;<br />
<br />
&amp;lt;/mx:Script&amp;gt;&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>Now, all we do is get an instance to the model. The model instance is bindable so that the view can bind to properties on the model. I say the model because Cairngorm only has one. The code in the model goes as far as possible in ActionScript 3 to make sure that nothing can instantiate the model except the model&#8217;s class. If you haven&#8217;t seen a Singleton implementation in AS3, here our Model as an example. First, there&#8217;s a private class variable to hold the singleton instance:</p>
<p><strong>twitteria_cairngorm/src/com/insideria/twitteria/model/TwitteRIAModel.as #10</strong></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
&lt;span class=&quot;category1&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;var&lt;/span&gt; instance:TwitteRIAModel;&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>Then, since we can&#8217;t have private constructors in AS3, the constructor doesn&#8217;t allow any other class to call new TwitteRIAModel() unless it passes an instance of the Private class:</p>
<p><strong>twitteria_cairngorm/src/com/insideria/twitteria/model/TwitteRIAModel.as #27-31 (formatted)</strong></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
&lt;span class=&quot;category1&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;function&lt;/span&gt; TwitteRIAModel(access:Private) {<br />
&nbsp; &nbsp; &nbsp; &lt;span class=&quot;category1&quot;&gt;if&lt;/span&gt; (access == &lt;span class=&quot;category1&quot;&gt;null&lt;/span&gt;) {<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;span class=&quot;category1&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;new&lt;/span&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;CairngormError(<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;CairngormMessageCodes.SINGLETON_EXCEPTION,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&quot;&lt;span class=&quot;quote&quot;&gt;XCLModelLocator&lt;/span&gt;&quot;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;);<br />
&nbsp; &nbsp; &nbsp; &nbsp;}<br />
}&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>which is defined on line 45, outside the package, making it virtually invisible outside of this file.</p>
<p><strong>twitteria_cairngorm/src/com/insideria/twitteria/model/TwitteRIAModel.as #45</strong></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
&lt;span class=&quot;category1&quot;&gt;class&lt;/span&gt; Private {}&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>And finally the getInstance method returns the instance, creating it if it hasn&#8217;t already been created.</p>
<p><strong>twitteria_cairngorm/src/com/insideria/twitteria/model/TwitteRIAModel.as #33-38</strong></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
&lt;span class=&quot;category1&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;function&lt;/span&gt; getInstance():TwitteRIAModel {<br />
&nbsp; &nbsp; &nbsp; &lt;span class=&quot;category1&quot;&gt;if&lt;/span&gt; (instance == &lt;span class=&quot;category1&quot;&gt;null&lt;/span&gt;) {<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; instance = &lt;span class=&quot;category1&quot;&gt;new&lt;/span&gt; TwitteRIAModel(&lt;span class=&quot;category1&quot;&gt;new&lt;/span&gt; Private());<br />
&nbsp; &nbsp; &nbsp; &nbsp;}<br />
&nbsp; &nbsp; &nbsp; &lt;span class=&quot;category1&quot;&gt;return&lt;/span&gt; instance;<br />
}&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>So much for Singletons. We&#8217;ll have more to say about them later. Back to the Application. Now that we have the model to hold state for the application, we can point the ViewStack at the model.</p>
<p><strong>twitteria_cairngorm/src/twitteria_cairngorm.mxml #23-26 (formatted)</strong></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
&amp;lt;mx:ViewStack selectedIndex=&quot;&lt;span class=&quot;quote&quot;&gt;{model.mainViewIndex}&lt;/span&gt;&quot;&amp;gt;<br />
&nbsp; &nbsp; &nbsp;&amp;lt;view:LoginView id=&quot;&lt;span class=&quot;quote&quot;&gt;loginView&lt;/span&gt;&quot; /&amp;gt;<br />
<br />
&nbsp; &nbsp; &nbsp;&amp;lt;view:MainView id=&quot;&lt;span class=&quot;quote&quot;&gt;mainView&lt;/span&gt;&quot; /&amp;gt;<br />
&amp;lt;/mx:ViewStack&amp;gt;&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>Also note that the LoginView and MainView here no longer share the username and password between them, nor does the LoginView inform the Application of the login event. We&#8217;ll get to how those changed in a moment. For now, there&#8217;s one last important line on the Application:</p>
<p><strong>twitteria_cairngorm/src/twitteria_cairngorm.mxml #15</strong></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
&amp;lt;controller:TwitteRIAController id=&quot;&lt;span class=&quot;quote&quot;&gt;controller&lt;/span&gt;&quot; /&amp;gt;&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>The Cairngorm FrontController needs to be instantiated early in the application&#8217;s lifecycle, and that&#8217;s generally done by defining it in MXML right in the root application. Another thing that&#8217;s usually instantiated alongside the controller is the ServiceLocator, which is generally a file that defines any services the application accesses to keep them all in the same place. Since our application doesn&#8217;t use the normal HTTPService or RemoteObject you usually see in a Cairngorm application, we don&#8217;t use the ServiceLocator.</p>
<p>The Controller, as mentioned above, is what takes care of capturing dispatched CairngormEvents and instantiating and executing the corresponding commands. You never actually interact directly with the controller in code, but you do wire up events to commands there, as shown here:</p>
<p><strong>twitteria_cairngorm/src/com/insideria/twitteria/controller/TwitteRIAController.as #13-17 (formatted)</strong></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
&lt;span class=&quot;category1&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;category2&quot;&gt;initialize&lt;/span&gt;():&lt;span class=&quot;category1&quot;&gt;void&lt;/span&gt; {<br />
&nbsp; &nbsp; &nbsp; addCommand(<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;LogInEvent.LogIn_Event, LogInCommand);<br />
&nbsp; &nbsp; &nbsp; addCommand(<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;LoadTimelineEvent.LoadTimeline_Event, LoadTimelineCommand);<br />
&nbsp; &nbsp; &nbsp; addCommand(<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;SetStatusEvent.SetStatus_Event, SetStatusCommand);<br />
}&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>Now whenever, for instance, a LogInEvent is dispatched, the FrontController instantiates a LogInCommand and executes it.</p>
<p><strong>Logging In</strong></p>
<p>Now lets look at logging in. Where before we just had the LoginView&#8217;s username and password bound to the MainView, we&#8217;re going to take a more scalable approach this time. What we really want is to keep the username and password around so that we can access them from anywhere we need them. That&#8217;s what the model is for. Now look at the LoginView&#8217;s login method, which before emitted an event:</p>
<p><strong>twitteria_cairngorm/src/com/insideria/twitteria/view/LoginView.mxml #7-9</strong></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
&lt;span class=&quot;category1&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;function&lt;/span&gt; login():&lt;span class=&quot;category1&quot;&gt;void&lt;/span&gt; {<br />
&nbsp; &nbsp; &nbsp; &lt;span class=&quot;category1&quot;&gt;new&lt;/span&gt; LogInEvent(usernameText.&lt;span class=&quot;category2&quot;&gt;text&lt;/span&gt;, passwordText.&lt;span class=&quot;category2&quot;&gt;text&lt;/span&gt;).dispatch();<br />
}&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>Now the method dispatches a LogInEvent, which holds a username and a password. When it&#8217;s dispatched with its own dispatch method, the LogInCommand is instantiated and executed, with the event passed along.</p>
<p><strong>twitteria_cairngorm/src/com/insideria/twitteria/command/LoginCommand.as #13-19</strong></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
&lt;span class=&quot;category1&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;function&lt;/span&gt; execute(event:CairngormEvent):&lt;span class=&quot;category1&quot;&gt;void&lt;/span&gt; {<br />
&nbsp; &nbsp; &nbsp; &lt;span class=&quot;category1&quot;&gt;var&lt;/span&gt; evt:LogInEvent = event as LogInEvent;<br />
&nbsp; &nbsp; &nbsp; model.username = evt.username;<br />
&nbsp; &nbsp; &nbsp; model.&lt;span class=&quot;category2&quot;&gt;password&lt;/span&gt; = evt.&lt;span class=&quot;category2&quot;&gt;password&lt;/span&gt;;<br />
&nbsp; &nbsp; &nbsp; model.mainViewIndex = TwitteRIAModel.MAIN_VIEW;<br />
}&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>After setting the username and password properties on the model to the values on the event, the command changes the mainViewIndex property to the MAIN_VIEW constant on the model. If you remember, the ViewStack in the application had its index bound to model.mainViewIndex.</p>
<p><strong>twitteria_cairngorm/src/twitteria_cairngorm.mxml #23 (formatted)</strong></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
&amp;lt;mx:ViewStack selectedIndex=&quot;&lt;span class=&quot;quote&quot;&gt;{model.mainViewIndex}&lt;/span&gt;&quot;&amp;gt;&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>The constants on the model help give some idea what they are used for:</p>
<p><strong>twitteria_cairngorm/src/com/insideria/twitteria/model/TwitteRIAModel.as #16-19</strong></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
&lt;span class=&quot;category1&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;static&lt;/span&gt; const LOGIN_VIEW:int &nbsp;= 0;<br />
&lt;span class=&quot;category1&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;static&lt;/span&gt; const MAIN_VIEW:int &nbsp; = 1;<br />
[Bindable]<br />
<br />
&lt;span class=&quot;category1&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;var&lt;/span&gt; mainViewIndex:int &nbsp; &nbsp; &nbsp; &nbsp;= LOGIN_VIEW;&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>So when the LoginCommand changes the mainViewIndex to MAIN_VIEW, the ViewStack changes to show MainView.</p>
<p>There are two examples of how the Cairngorm model holds both application state and view state. You also see can see an example of how a Cairngorm command is tasked with a specific responsibility, in this case setting credentials and making sure the view state matches the logged in view &#8211; basically taking care of what needs to be done to log in, just like the command name leads you to believe. In this way the commands and FrontController together make up the Controller part of MVC for Cairngorm.</p>
<p>I like that about Cairngorm. If you want to know how the app works and where that work is done, you just need to look through the command directory and see a list of descriptive verbs that tell you what takes place and what class does it.</p>
<p><strong>Loading the Timeline</strong></p>
<p>Now let&#8217;s look at how we load the timeline. Again, when the MainView&#8217;s creation is complete, the init method is called:</p>
<p><strong>twitteria_cairngorm/src/com/insideria/twitteria/view/MainView.mxml #14-16</strong></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
&lt;span class=&quot;category1&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;category2&quot;&gt;init&lt;/span&gt;():&lt;span class=&quot;category1&quot;&gt;void&lt;/span&gt; {<br />
&nbsp; &nbsp; &nbsp; &lt;span class=&quot;category1&quot;&gt;new&lt;/span&gt; LoadTimelineEvent().dispatch();<br />
}&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>Instead of doing any work inside the MainView, like we did before, now we dispatch a CairngormEvent that loads the timeline. That event corresponds to the LoadTimelineCommand.</p>
<p><strong>twitteria_cairngorm/src/com/insideria/twitteria/command/LoadTimelineCommand.as #16-20</strong></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
&lt;span class=&quot;category1&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;function&lt;/span&gt; execute(event:CairngormEvent):&lt;span class=&quot;category1&quot;&gt;void&lt;/span&gt; {<br />
&nbsp; &nbsp; &nbsp; &lt;span class=&quot;category1&quot;&gt;var&lt;/span&gt; evt:LoadTimelineEvent = event as LoadTimelineEvent;<br />
&nbsp; &nbsp; &nbsp; &lt;span class=&quot;category1&quot;&gt;var&lt;/span&gt; delegate:TwitterDelegate = &lt;span class=&quot;category1&quot;&gt;new&lt;/span&gt; TwitterDelegate(&lt;span class=&quot;category1&quot;&gt;this&lt;/span&gt;);<br />
&nbsp; &nbsp; &nbsp; delegate.loadTimeline();<br />
}&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>The execute method doesn&#8217;t do that much, in fact it delegates responsibility to the TwitterDelegate. If you remember, delegates are the guys that wrap the service API and cushion the rest of the app from changes to the services. All we need to know here is that the delegate will load the timeline, and we ask it to do so.</p>
<p>I should make a note here that I&#8217;m breaking a bit with Cairngorm convention. Generally Cairngorm has you define one delegate for each event/command pair. That gets a little chunky for my taste, and instead I usually define one delegate for every resource I&#8217;m accessing on the service side. For instance if I had a user service with an API for creating, updating, deleting, getting a user, and getting all users, I&#8217;d have one delegate for users which would have methods to execute each of those operations. Again, this is not Cairngorm convention, this is my way of doing things. It&#8217;s not like I&#8217;m hurting Cairngorm, though, and it shows that the framework is flexible enough to meet your needs, or in this case, a matter of taste.</p>
<p>Let&#8217;s look at the delegate. In the constructor you can see more characteristic Cairngorm code:</p>
<p><strong>twitteria_cairngorm/src/com/insideria/twitteria/business/TwitterDelegate.as #20-21</strong></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
&lt;span class=&quot;category1&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;function&lt;/span&gt; TwitterDelegate(responder:IResponder) {<br />
&nbsp; &nbsp; &nbsp; &lt;span class=&quot;category1&quot;&gt;this&lt;/span&gt;.responder = responder;&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>Notice how the argument to the constructor isn&#8217;t a Command, but an IResponder. That interface is part of the mx.rpc package that ships with Flex, and it describes two methods &#8211; result and fault. Cairngorm makes use of this interface for commands that are asynchronous, which means that they &#8220;fire and forget&#8221; calls off to the service, and expect to be called back when the service returns from the call. If you&#8217;ve been around Flex and Flash for any length of time, you know that just about everything follows this pattern of callbacks. In this case Cairngorm designed delegates to take an object that has a method, result, to callback when a service returns with a result, and fault, a method to call back if something goes wrong. It doesn&#8217;t care how that happens in the delegate or service, and the command implementing IResponder doesn&#8217;t need to know either. It just needs to know if the call worked or didn&#8217;t, and then act accordingly. The responder is set into a private property for later use.</p>
<p><strong>twitteria_cairngorm/src/com/insideria/twitteria/business/TwitterDelegate.as #23-25 (formatted)</strong></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
twitterService = &lt;span class=&quot;category1&quot;&gt;new&lt;/span&gt; Twitter();<br />
twitterService.setAuthenticationCredentials(<br />
&nbsp; &nbsp; &nbsp;model.username, model.&lt;span class=&quot;category2&quot;&gt;password&lt;/span&gt;<br />
);<br />
twitterService.addEventListener(<br />
&nbsp; &nbsp; &nbsp;TwitterEvent.ON_FRIENDS_TIMELINE_RESULT,<br />
&nbsp; &nbsp; &nbsp;friendsTimelineLoaded<br />
);&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>Next, the delegate creates an instance of Twitter, sets the credentials to the username and password the LoginCommand stored on the model, and registers some callbacks on the twitter service. Most times you&#8217;ll see RemoteObjects or HTTPServices inside delegates and things look a little different than you see here. RemoteObjects call AMF services, and they know how to deal with responders. Luckily though, the delegate is flexible enough to deal with our situation where we need to instantiate and set up the service right here.</p>
<p>Once the callbacks for each type of Twitter service call, a call of that type should call back to the method in the delegate. When we ask for the timeline, callbacks should go to the friendsTimelineLoaded method:</p>
<p><strong>twitteria_cairngorm/src/com/insideria/twitteria/business/TwitterDelegate.as #49-51</strong></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
&lt;span class=&quot;category1&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;function&lt;/span&gt; friendsTimelineLoaded(te:TwitterEvent):&lt;span class=&quot;category1&quot;&gt;void&lt;/span&gt; {<br />
&nbsp; &nbsp; &nbsp; responder.result(te.&lt;span class=&quot;category2&quot;&gt;data&lt;/span&gt; as &lt;span class=&quot;category2&quot;&gt;Array&lt;/span&gt;);<br />
}&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>And that method just calls the result method on the responder with the timeline data it gets from Twitter. This is clean, because now the command doesn&#8217;t need to know anything about the Twitter class or the TwitterEvent that comes back, it just needs to know about an array of tweets that comes to the result method.</p>
<p>By the way there&#8217;s no fault thrown from Twitterscript, so the fault method isn&#8217;t going to ever be called, but you can imagine how it would be if there were.</p>
<p>Now, when the command calls loadTimeline, the delegate does this:</p>
<p><strong>twitteria_cairngorm/src/com/insideria/twitteria/business/TwitterDelegate.as #29-38 (formatted)</strong></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
&lt;span class=&quot;category1&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;function&lt;/span&gt; loadTimeline():&lt;span class=&quot;category1&quot;&gt;void&lt;/span&gt; {<br />
&nbsp; &nbsp; &nbsp; &lt;span class=&quot;category1&quot;&gt;if&lt;/span&gt; (useDummyData) {<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;span class=&quot;category1&quot;&gt;var&lt;/span&gt; te:TwitterEvent = &lt;span class=&quot;category1&quot;&gt;new&lt;/span&gt; TwitterEvent(<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;TwitterEvent.ON_FRIENDS_TIMELINE_RESULT<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; );<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; te.&lt;span class=&quot;category2&quot;&gt;data&lt;/span&gt; = getDummyData();<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; friendsTimelineLoaded(te);<br />
&nbsp; &nbsp; &nbsp; &nbsp;} &lt;span class=&quot;category1&quot;&gt;else&lt;/span&gt; {<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; twitterService.loadFriendsTimeline(model.username);<br />
&nbsp; &nbsp; &nbsp; &nbsp;}<br />
}&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>And there&#8217;s our old friend, the dummy data. Although this still isn&#8217;t what I&#8217;d call a good way of choosing which data to load, real or fake, at least it&#8217;s all sectioned off into the delegate and no one else needs to know how it&#8217;s done. That&#8217;s called encapsulation, and just like when the delegate wraps the service, it cushions the rest of the application from change.</p>
<p>When LoadTimelineCommand finally gets result called, it creates a new ArrayCollection to wrap the array of tweets and places it on the model.</p>
<p><strong>twitteria_cairngorm/src/com/insideria/twitteria/command/LoadTimelineCommand.as #22-25</strong></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
&lt;span class=&quot;category1&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;function&lt;/span&gt; result(result:&lt;span class=&quot;category2&quot;&gt;Object&lt;/span&gt;):&lt;span class=&quot;category1&quot;&gt;void&lt;/span&gt; {<br />
&nbsp; &nbsp; &nbsp; &lt;span class=&quot;category1&quot;&gt;var&lt;/span&gt; stati:&lt;span class=&quot;category2&quot;&gt;Array&lt;/span&gt; = result as &lt;span class=&quot;category2&quot;&gt;Array&lt;/span&gt;;<br />
&nbsp; &nbsp; &nbsp; model.currentTweets = &lt;span class=&quot;category1&quot;&gt;new&lt;/span&gt; ArrayCollection(stati);<br />
}&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>That&#8217;s a very Cairngorm like sequence, there. Command calls delegate, delegate calls service, service returns to delegate (or sometimes straight to command), and then on to result, which changes something on the model. Then Flex binding takes over and modifies the view.</p>
<p><strong>twitteria_cairngorm/src/com/insideria/twitteria/view/MainView.mxml #32</strong></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
dataProvider=&quot;&lt;span class=&quot;quote&quot;&gt;{model.currentTweets}&lt;/span&gt;&quot;&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>Since the list in the main view is bound to the model&#8217;s currentTweets property, it will reset itself to show the new list. Slick!</p>
<p><strong>Setting Status</strong></p>
<p>There&#8217;s not a lot to show for setting status, since everything works pretty much the same. In fact, that&#8217;s something you can get used to with Cairngorm &#8211; if you want to know what happens because of a user interaction, find the command that gets executed and you&#8217;ll probably learn everything you need to know about what goes on. If not, you can follow back to the delegate, but the command does the bulk of the heavy lifting on the client side. Here&#8217;s SetStatusCommand&#8217;s execute:</p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
&lt;span class=&quot;category1&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;function&lt;/span&gt; execute(event:CairngormEvent):&lt;span class=&quot;category1&quot;&gt;void&lt;/span&gt; {<br />
&nbsp; &nbsp; &nbsp; &lt;span class=&quot;category1&quot;&gt;var&lt;/span&gt; evt:SetStatusEvent = event as SetStatusEvent;<br />
&nbsp; &nbsp; &nbsp; &lt;span class=&quot;category1&quot;&gt;var&lt;/span&gt; delegate:TwitterDelegate = &lt;span class=&quot;category1&quot;&gt;new&lt;/span&gt; TwitterDelegate(&lt;span class=&quot;category1&quot;&gt;this&lt;/span&gt;);<br />
&nbsp; &nbsp; &nbsp; delegate.setStatus(evt.statusText);<br />
}&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>and result:</p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
&lt;span class=&quot;category1&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;function&lt;/span&gt; result(result:&lt;span class=&quot;category2&quot;&gt;Object&lt;/span&gt;):&lt;span class=&quot;category1&quot;&gt;void&lt;/span&gt; {<br />
&nbsp; &nbsp; &nbsp; &lt;span class=&quot;category1&quot;&gt;new&lt;/span&gt; LoadTimelineEvent().dispatch();<br />
}&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>Notice how we have to dispatch the LoadTimelineEvent from the result? That&#8217;s one thing that some other frameworks try to work around. This command&#8217;s responsibility is telling Twitter what sweet new <a href="http://icanhascheezburger.com/">lolcat</a> picture we just posted or <a href="http://www.youjustgotrickrolled.com">trojan-linking in a Rick Astley</a> video, not loading the timeline, but now we&#8217;ve tied this command up with loading the timeline. We could have had the MainView dispatch the next event if we somehow alerted the view to the fact that the status had been set, but that&#8217;s a little iffy too. In any case, the next thing that needs to happen when the status is set is to reload the timeline, so we do it here, and that&#8217;s all we need to do.</p>
<p>Keep that in mind for when we move on to other frameworks, because we&#8217;re out of time for today. You&#8217;ve seen how we&#8217;ve used Cairngorm&#8217;s CairngormEvents, the command pattern, delegates, and a singleton model to clean things up considerably from where we left things off last time. Next time we&#8217;ll see another framework that aims to clean some of the framework code out of the view, and rebuild our application using PureMVC.</p>
<p><a href="http://www.insideria.com/tony-hillerson/">Read more from<br />
Tony Hillerson</a></p>


<p>Related posts:<ol><li><a href='http://flex.exposedout.net/2009/01/16/frameworkquest-2008-part-4-ioc-with-swiz/' rel='bookmark' title='Permanent Link: FrameworkQuest 2008 Part 4: IoC With Swiz'>FrameworkQuest 2008 Part 4: IoC With Swiz</a></li>
<li><a href='http://flex.exposedout.net/2009/01/16/frameworkquest-2008-part-3-framework-agnostic-views-with-puremvc/' rel='bookmark' title='Permanent Link: FrameworkQuest 2008 Part 3: Framework Agnostic Views with PureMVC'>FrameworkQuest 2008 Part 3: Framework Agnostic Views with PureMVC</a></li>
<li><a href='http://flex.exposedout.net/2009/01/16/frameworkquest-2008-part-5-mate-the-pure-mxml-framework/' rel='bookmark' title='Permanent Link: FrameworkQuest 2008 Part 5: Mate, the Pure MXML Framework'>FrameworkQuest 2008 Part 5: Mate, the Pure MXML Framework</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://flex.exposedout.net/2009/01/16/frameworkquest-2008-part-2-get-control-with-cairngorm/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>FrameworkQuest 2008 : Introduction</title>
		<link>http://flex.exposedout.net/2009/01/16/frameworkquest-2008-introduction/</link>
		<comments>http://flex.exposedout.net/2009/01/16/frameworkquest-2008-introduction/#comments</comments>
		<pubDate>Fri, 16 Jan 2009 10:38:56 +0000</pubDate>
		<dc:creator>Vikram singh</dc:creator>
				<category><![CDATA[flex]]></category>
		<category><![CDATA[framework]]></category>

		<guid isPermaLink="false">http://guavus.wordpress.com/?p=155</guid>
		<description><![CDATA[I am thankful to Tony Hillerson for writing this post. please find the original post here print listen FrameworkQuest 2008: Introduction FrameworkQuest 2008 Part 2: Get Control with Cairngorm FrameworkQuest 2008 Part 3: Agnostic Views with PureMVC FrameworkQuest 2008 Part 4: IoC With Swiz FrameworkQuest 2008 Part 5: Mate, the Pure MXML Framework FrameworkQuest 2008 [...]


Related posts:<ol><li><a href='http://flex.exposedout.net/2009/01/16/frameworkquest-2008-part-4-ioc-with-swiz/' rel='bookmark' title='Permanent Link: FrameworkQuest 2008 Part 4: IoC With Swiz'>FrameworkQuest 2008 Part 4: IoC With Swiz</a></li>
<li><a href='http://flex.exposedout.net/2009/01/16/frameworkquest-2008-part-2-get-control-with-cairngorm/' rel='bookmark' title='Permanent Link: FrameworkQuest 2008 Part 2: Get Control with Cairngorm'>FrameworkQuest 2008 Part 2: Get Control with Cairngorm</a></li>
<li><a href='http://flex.exposedout.net/2009/01/16/frameworkquest-2008-part-5-mate-the-pure-mxml-framework/' rel='bookmark' title='Permanent Link: FrameworkQuest 2008 Part 5: Mate, the Pure MXML Framework'>FrameworkQuest 2008 Part 5: Mate, the Pure MXML Framework</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>I am thankful to <strong>Tony Hillerson</strong> for writing this post.<br />
please find the original post <a href="http://www.insideria.com/2008/12/frameworkquest-2008-introducti.html">here</a></p>
<div class="button"><a href="http://www.insideria.com/print/33653.html" target="_blank">print <img src="http://insideria.com/riaimages/printtag.jpg" style="border:none;" /></a><br />
<a target="_new" href="http://asp2.readspeaker.net/cgi-bin/oreillyrsone?lang=us&amp;voice=Paul&amp;customerid=171&amp;url=http://www.insideria.com/2008/12/frameworkquest-2008-introducti.html">listen <img src="http://www.oreillynet.com/images/icon_listen_small.gif" width="10" height="9" alt="Speech Icon" /></a></div>
<blockquote><p>
<a href="http://www.insideria.com/2008/12/frameworkquest-2008-introducti.html">FrameworkQuest 2008: Introduction</a><br />
<a href="http://www.insideria.com/2008/12/frameworkquest-2008-part-2-get.html?CMP=AFC-ak_article&amp;ATT=FrameworkQuest+2008++Part+2%3A+Get+Control+with+Cairngorm">FrameworkQuest 2008 Part 2: Get Control with Cairngorm</a><br />
<a href="http://www.insideria.com/2008/12/frameworkquest-2008-part-3-fra.html?CMP=AFC-ak_article&amp;ATT=FrameworkQuest+2008+Part+3%3A+Framework+Agnostic+Views+with+PureMVC">FrameworkQuest 2008 Part 3: Agnostic Views with PureMVC</a><br />
<a href="http://www.insideria.com/2008/12/frameworkquest-2008-part-4-ioc.html?CMP=AFC-ak_article&amp;ATT=FrameworkQuest+2008+Part+4%3A+IoC+With+Swiz">FrameworkQuest 2008 Part 4: IoC With Swiz</a><br />
<a href="http://www.insideria.com/2008/12/frameworkquest-2008-part-5-mat.html?CMP=AFC-ak_article&amp;ATT=FrameworkQuest+2008+Part+5%3A+Mate%2c+the+Pure+MXML+Framework">FrameworkQuest 2008 Part 5: Mate, the Pure MXML Framework</a><br />
<a href="http://www.insideria.com/2009/01/frameworkquest-2008-part-6-the.html?CMP=AFC-ak_article&amp;ATT=FrameworkQuest+2008+Part+6%3A+The+Exciting+Conclusion">FrameworkQuest 2008 Part 6: The Exciting Conclusion</a>
</p></blockquote>
<h1>FrameworkQuest 2008</h1>
<p>
<strong>Part 1: Take a Step Back</strong><br />
</p>
<p><strong>Frameworks</strong></p>
<p>Frameworks, frameworks, frameworks. We talk about them all the time. What&#8217;s the best one? Which one ticks the most boxes off the pattern checklist? What&#8217;s everyone using these days? We talk about frameworks so much that it deserves to be written like this:</p>
<p> <img /><br />
<strong>FRAMEWORKS!!!</strong></p>
<p><strong>We Work Hard, So You Don&#8217;t Have To</strong></p>
<p>This series of articles is scientifically designed to help you get an understanding of the major Flex Frameworks on the market today.</p>
<ul>
<li>•	What are your choices?</li>
<li>•	How do they work?</li>
<li>•	What do they preach, and is it hard to practice what they preach?</li>
<li>•	How does Brand X stack up against my brand of choice?</li>
<li>•	And the most important question: Does this framework make me joyful?</li>
</ul>
<p>I could have gone about this quest multiple ways, but the way I chose was slightly more organic than the more obvious rundown of features, and I hope you get more out of this approach.</p>
<p>I&#8217;ve taken a simple application and built it five ways. Once with no framework at all, and once each with these Flex Frameworks:</p>
<ul>
<li>•	Cairngorm</li>
<li>•	PureMVC</li>
<li>•	Swiz</li>
<li>•	Mate</li>
</ul>
<p>All source code is available at <a href="http://github.com/thillerson/twitteria" target="_blank">http://github.com/thillerson/twitteria</a>. To get the code, either check the project out using Git, or if you just want the source as a zip file, click the &#8220;download&#8221; button. The project targets <a href="http://www.adobe.com/products/air/" target="_blank">Adobe&#8217;s AIR</a> platform. I expect that you know how to work with and build AIR projects already, so I don&#8217;t take any time to explain that.</p>
<p>In the interest of full disclosure, I should let you know that I hadn&#8217;t used any of these frameworks before except Cairngorm, which I use pretty much every day. I did research and write a chapter on Cairngorm and PureMVC for <a href="http://www.amazon.com/Flex-Rails-Building-Internet-Applications/dp/0321543378" target="_blank">Flex on Rails</a> (shipping Q1 2009), so I was already familiar with PureMVC, but I&#8217;m most used to building with Cairngorm, and I had never worked with Swiz or Mate at all before this article was written.</p>
<p>At the end, in the last article in the series, I&#8217;ll put forward a subjective rating system to give you an idea of what I thought of each framework.</p>
<p><strong>What Good is a Framework?</strong></p>
<p>Let&#8217;s take a step back. Why do we use frameworks? Here&#8217;s a graphic whose idea I stole from a slide in <a href="http://www.youtube.com/watch?v=i6Fr65PFqfk" target="_blank">Cal Henderson&#8217;s Djangocon Keynote</a> thoughtfully entitled &#8220;Why I Hate</p>
<p><img /></p>
<p>Django&#8221;. This graph shows, with the best science available to the author, why we use frameworks. No frameworks were harmed in the making of this graphic.</p>
<p>Speaking in terms of complexity, a very simple application has a small advantage in development speed over an application of similar complexity using a framework. There are rules and a little bit of red tape you have to cut through to use the framework, so for a dead-simple app skipping a framework is a win in development speed. </p>
<p>Frameworks start to show value when you want to do things that a lot of other people want to do, like call remote services, keep things clean and separated, and in general think about your app based on similarities to every other application out there. That&#8217;s what makes a pattern &#8211; common use.<br />
Following the rules of the framework pays off in productivity. You have to think less about how you want to do what you want to do, because the framework has ready, commonly accepted answers for you.</p>
<p>As complexity goes up, development is still pretty speedy, especially in a team situation, because the organization the framework imposes is paying off more and more. It&#8217;s probably easy to remember where functionality is because you know where it fits into the framework&#8217;s notion of where things should be. Development without a framework is slower because you&#8217;re either mired in disorganization or you&#8217;re spending extra time building something like a framework.</p>
<p>Things get tricky once you get to the 80/20 rule, if your app gets more complex than most. Frameworks may even make it difficult to do some things you want because at this level of complexity you&#8217;re beyond the common cases the framework solves and the rules are making it hard to do what you want. At this point it may even be easier to do things with your homegrown solution because you&#8217;re building things the way you need them.</p>
<p>At the end of the graph I&#8217;ll freely admit that I&#8217;m making things up. Let&#8217;s call this end of the graph &#8220;the point where the framework catches up because the author is in favor of frameworks&#8221; or simply the Deus Ex Machina section of the graph. In any case, my gut tells me that frameworks still have something to give even when applications get really complex.</p>
<p>The point of this artificial graph is to show that we use frameworks because at most levels of complexity of an application, a framework makes us more productive. </p>
<p><strong>TwitteRIA &#8211; Don&#8217;t Worry, Anyone Can Get It</strong></p>
<p>Ok, now on to the fun. The app we&#8217;re going to build was suggested by Anthony Franco, President of my company, EffectiveUI. He won hands down in a battle royale on <a href="http://twitter.com/" target="_blank">Twitter</a>, the microblogging site, the Great Chatroom of The Internet, where I asked for ideas from anyone on what app to build for this article. Sometimes the simplest person can have a flash of brilliance, and he suggested that I build a Twitter client. The prize was a mention in this article, so here it is: Anthony, you&#8217;re the best looking boss I&#8217;ve ever had! Great hair, nice teeth, a class act all around!</p>
<p>The application that I&#8217;ve used to build with each of these frameworks is a simple Twitter client that implements these user stories:</p>
<ul>
<li>1.	Retrieve authenticated user&#8217;s timeline</li>
<li>2.	Set authenticated user&#8217;s status</li>
<li>3.	Be exceptionally pleasing to the authenticated user&#8217;s eye<br />
<img /></li>
</ul>
<p>You can be your own judge on number three, but numbers one and two are simple enough to not get in the way, and complex enough to exercise the frameworks. So without further ado, I give you TwitteRIA. Some of you may have it already, so to speak. I know I do.</p>
<p>All five projects use a special version of Twitterscript, which you can get here: <a href="http://github.com/thillerson/twitterscript/" target="_blank">http://github.com/thillerson/twitterscript/</a>. It&#8217;s a version of Peter Armstrong&#8217;s, which is here: <a href="http://github.com/peterarmstrong/twitterscript/" target="_blank">http://github.com/peterarmstrong/twitterscript/</a>, and in turn a version of the original, which is here: <a href="http://code.google.com/p/twitterscript/" target="_blank">http://code.google.com/p/twitterscript/</a>. Credit where credit is due: all I did in my version was add back in the ability to authenticate users safely. Due to Flash security limitations, this means you can only use the library in AIR projects if you need to authenticate. The swc is included in the lib directory of each project. Since the application is written for the AIR platform you&#8217;ll need to have either the AIR SDK or Flex Builder installed.</p>
<p>Now let&#8217;s go through the framework-less application one feature at a time. Try to keep a lookout for problems in the application that you think a framework may be able to help solve.</p>
<p><strong>Logging In</strong></p>
<p>Logging in with Twitterscript is not quite like logging in to any other services. All we need to do is call a method on an instance of the Twitter object we&#8217;re going to use to interact with Twitter. Because of that, all we need to do is capture the login credentials of a user in memory, and then go on to load the user&#8217;s timeline. To do this, in the root application file we have two views in a view stack, like so:</p>
<p><strong>twitteria_raw/src/twitteria_raw.mxml #24-27 (formatted)</strong></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
&amp;lt;mx:ViewStack<br />
&nbsp; &nbsp; bottom=&quot;&lt;span class=&quot;quote&quot;&gt;0&lt;/span&gt;&quot; left=&quot;&lt;span class=&quot;quote&quot;&gt;0&lt;/span&gt;&quot; right=&quot;&lt;span class=&quot;quote&quot;&gt;0&lt;/span&gt;&quot; top=&quot;&lt;span class=&quot;quote&quot;&gt;30&lt;/span&gt;&quot;<br />
&nbsp; &nbsp; selectedIndex=&quot;&lt;span class=&quot;quote&quot;&gt;{viewIndex}&lt;/span&gt;&quot;&amp;gt;<br />
<br />
&nbsp; &nbsp; &amp;lt;local:LoginView id=&quot;&lt;span class=&quot;quote&quot;&gt;loginView&lt;/span&gt;&quot; login=&quot;&lt;span class=&quot;quote&quot;&gt;login()&lt;/span&gt;&quot; /&amp;gt;<br />
&nbsp; &nbsp; &amp;lt;local:MainView id=&quot;&lt;span class=&quot;quote&quot;&gt;mainView&lt;/span&gt;&quot;<br />
&nbsp; &nbsp; &nbsp; &nbsp; username=&quot;&lt;span class=&quot;quote&quot;&gt;{loginView.username}&lt;/span&gt;&quot;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &lt;span class=&quot;category2&quot;&gt;password&lt;/span&gt;=&quot;&lt;span class=&quot;quote&quot;&gt;{loginView.password}&lt;/span&gt;&quot; /&amp;gt;<br />
<br />
&amp;lt;/mx:ViewStack&amp;gt;&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>LoginView captures a username and password and exposes them as public properties that we can bind into MainView. If you said &#8220;That&#8217;s not very scalable, Tony!!&#8221; well, you&#8217;re right. It&#8217;s one problem we can help fix with a framework, but for now it works. Inside LoginView, when enter is pressed on the password field, this method runs:</p>
<p><strong>twitteria_raw/src/LoginView.mxml #12-16</strong></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
&lt;span class=&quot;category1&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;function&lt;/span&gt; login():&lt;span class=&quot;category1&quot;&gt;void&lt;/span&gt; {<br />
&nbsp; &nbsp; username = usernameText.&lt;span class=&quot;category2&quot;&gt;text&lt;/span&gt;;<br />
&nbsp; &nbsp; &lt;span class=&quot;category2&quot;&gt;password&lt;/span&gt; = passwordText.&lt;span class=&quot;category2&quot;&gt;text&lt;/span&gt;;<br />
&nbsp; &nbsp; dispatchEvent(&lt;span class=&quot;category1&quot;&gt;new&lt;/span&gt; Event('&lt;span class=&quot;quote&quot;&gt;login&lt;/span&gt;'));<br />
}&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>This sets the public properties and then dispatches an event, which is listed here:</p>
<p><strong>twitteria_raw/src/LoginView.mxml #3-5</strong></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
&amp;lt;mx:Metadata&amp;gt;<br />
&nbsp; &nbsp; [Event(&lt;span class=&quot;category2&quot;&gt;name&lt;/span&gt;='&lt;span class=&quot;quote&quot;&gt;login&lt;/span&gt;', &lt;span class=&quot;category2&quot;&gt;type&lt;/span&gt;='&lt;span class=&quot;quote&quot;&gt;flash.events.Event&lt;/span&gt;')]<br />
<br />
&amp;lt;/mx:Metadata&amp;gt;&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>Back in the application file, we&#8217;ll catch that event and switch the index of the ViewStack to show MainView instead of LoginView with the help of a few constants:</p>
<p><strong>twitteria_raw/src/twitteria_raw.mxml #7-15</strong></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
&lt;span class=&quot;category1&quot;&gt;private&lt;/span&gt; const LOGIN_VIEW:&lt;span class=&quot;category1&quot;&gt;int&lt;/span&gt;&nbsp; = 0;<br />
<br />
&lt;span class=&quot;category1&quot;&gt;private&lt;/span&gt; const MAIN_VIEW:&lt;span class=&quot;category1&quot;&gt;int&lt;/span&gt; &nbsp; &nbsp; &nbsp; = 1;<br />
<br />
[Bindable]<br />
&lt;span class=&quot;category1&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;var&lt;/span&gt; viewIndex:&lt;span class=&quot;category1&quot;&gt;int&lt;/span&gt;&nbsp; &nbsp; &nbsp; = LOGIN_VIEW;<br />
<br />
&lt;span class=&quot;category1&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;function&lt;/span&gt; login():&lt;span class=&quot;category1&quot;&gt;void&lt;/span&gt; {<br />
&nbsp; &nbsp; viewIndex = MAIN_VIEW;<br />
}&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>Pretty simple so far. Now, since the creation policy on the ViewStack is the default, &#8220;auto&#8221;, views will be created when they are displayed. MainView will be created with the username and password from LoginView bound into its username and password fields. </p>
<p><strong>Loading the Timeline</strong></p>
<p>Once MainView is created, it runs the init method:</p>
<p><strong>twitteria_raw/src/MainView.mxml #20-37</strong></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
<br />
&lt;span class=&quot;category1&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;var&lt;/span&gt; twitterService:Twitter;<br />
&lt;span class=&quot;category1&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;var&lt;/span&gt; useDummyData:&lt;span class=&quot;category2&quot;&gt;Boolean&lt;/span&gt; = &lt;span class=&quot;category1&quot;&gt;true&lt;/span&gt;;<br />
<br />
&lt;span class=&quot;category1&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;category2&quot;&gt;init&lt;/span&gt;():&lt;span class=&quot;category1&quot;&gt;void&lt;/span&gt; {<br />
&nbsp; &nbsp; twitterService = &lt;span class=&quot;category1&quot;&gt;new&lt;/span&gt; Twitter();<br />
&nbsp; &nbsp; twitterService.setAuthenticationCredentials(username, &lt;span class=&quot;category2&quot;&gt;password&lt;/span&gt;);<br />
&nbsp; &nbsp; twitterService.addEventListener(<br />
&nbsp; &nbsp; &nbsp; &nbsp; TwitterEvent.ON_FRIENDS_TIMELINE_RESULT,<br />
&nbsp; &nbsp; &nbsp; &nbsp; friendsTimlineLoaded<br />
&nbsp; &nbsp; );<br />
&nbsp; &nbsp; twitterService.addEventListener(<br />
&nbsp; &nbsp; &nbsp; &nbsp; TwitterEvent.ON_SET_STATUS,<br />
&nbsp; &nbsp; &nbsp; &nbsp; statusSet<br />
&nbsp; &nbsp; );<br />
&nbsp; &nbsp; reload();<br />
}<br />
<br />
<br />
&lt;span class=&quot;category1&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;function&lt;/span&gt; reload():&lt;span class=&quot;category1&quot;&gt;void&lt;/span&gt; {<br />
&nbsp; &nbsp; &lt;span class=&quot;category1&quot;&gt;if&lt;/span&gt; (useDummyData) {<br />
&nbsp; &nbsp; &nbsp; &nbsp; currentTweets = &lt;span class=&quot;category1&quot;&gt;new&lt;/span&gt; ArrayCollection(getDummyData());<br />
&nbsp; &nbsp; } &lt;span class=&quot;category1&quot;&gt;else&lt;/span&gt; {<br />
&nbsp; &nbsp; &nbsp; &nbsp; twitterService.loadFriendsTimeline(username);<br />
&nbsp; &nbsp; }<br />
}&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>A few things are going on here. First, notice that we have a private member variable of type twitter.api.Twitter, which is the wrapper for all calls to the Twitter API. This class is provided by the Twitterscript library. </p>
<p>Next we have a very simple way of deciding to use dummy data instead of making calls to Twitter. This is important for a few reasons. </p>
<p>Consider what happens to development when Twitter is down. I know, I know, you&#8217;re probably saying &#8220;But Tony, in all my years on the web, I&#8217;ve never known Twitter to be down!&#8221;. Well, I&#8217;m here to tell you that it may happen one day, and your development effort should be prepared.</p>
<p>Another reason is that Twitter limits the number of messages you can send in an hour. Might as well make sure that doesn&#8217;t slow development either. A less important reason is that maybe you want to do a little development somewhere without Internet access. I want to be clear that the implementation here is a very simple, even dumb, way of doing this, but I&#8217;m going to use it later in the series to make a point, so bear with me.</p>
<p>The init method instantiates the Twitter object, sets the authentication credentials, and then sets up some event listeners for two types of event TwitterEvent.ON_FRIENDS_TIMELINE_RESULT and TwitterEvent.ON_SET_STATUS.</p>
<p>The reload method is what we call when we want to reload the timeline. Here&#8217;s where we use our simple method of switching in dummy data. If we&#8217;re using dummy data, we simply call the friend timeline callback method with some dummy data, but if not, we kick off a call to the actual service. When that gets back, the callback is executed:</p>
<p><strong>twitteria_raw/src/MainView.mxml #47-49</strong></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
&lt;span class=&quot;category1&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;function&lt;/span&gt; friendsTimlineLoaded(te:TwitterEvent):&lt;span class=&quot;category1&quot;&gt;void&lt;/span&gt; {<br />
&nbsp; &nbsp; currentTweets = &lt;span class=&quot;category1&quot;&gt;new&lt;/span&gt; ArrayCollection(te.&lt;span class=&quot;category2&quot;&gt;data&lt;/span&gt; as &lt;span class=&quot;category2&quot;&gt;Array&lt;/span&gt;);<br />
}&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>The callback sets a private member variable, currentTweets to an ArrayCollection that wraps the array of status messages in the result object or dummy data as the case may be. On down in the view section, there&#8217;s a list that shows the objects in the collection:</p>
<p><strong>twitteria_raw/src/MainView.mxml #90 (formatted)</strong></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
&amp;lt;mx:List<br />
&nbsp; &nbsp; id=&quot;&lt;span class=&quot;quote&quot;&gt;statusList&lt;/span&gt;&quot; &lt;span class=&quot;category2&quot;&gt;width&lt;/span&gt;=&quot;&lt;span class=&quot;quote&quot;&gt;100%&lt;/span&gt;&quot; &lt;span class=&quot;category2&quot;&gt;height&lt;/span&gt;=&quot;&lt;span class=&quot;quote&quot;&gt;100%&lt;/span&gt;&quot;<br />
&nbsp; &nbsp; styleName=&quot;&lt;span class=&quot;quote&quot;&gt;statusList&lt;/span&gt;&quot;<br />
&nbsp; &nbsp; itemRenderer=&quot;&lt;span class=&quot;quote&quot;&gt;TwitterStatusRenderer&lt;/span&gt;&quot;<br />
&nbsp; &nbsp; dataProvider=&quot;&lt;span class=&quot;quote&quot;&gt;{currentTweets}&lt;/span&gt;&quot; /&amp;gt;&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>The item renderer, TwitterStatusRenderer, displays a single twitter.api.data.TwitterStatus. Have a look at that if you&#8217;d like, but it&#8217;s pretty simple.</p>
<p>Not too much work for something pretty cool, eh? Of course there&#8217;s a lot more to a Twitter client like Twhirl or Twitteriffic, but it&#8217;s kind of neat to see status messages coming up with as little code as there is so far. But wait! There&#8217;s more! We can also update the current user&#8217;s status.</p>
<p><strong>Setting Status</strong></p>
<p>MainView has a TextInput that takes a status message, with a simple little method to tell the user how much of the 140 characters of Twitter message goodness they have left to them:</p>
<p><strong>twitteria_raw/src/MainView.mxml #96 (formatted)</strong></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
&amp;lt;mx:TextInput id=&quot;&lt;span class=&quot;quote&quot;&gt;statusText&lt;/span&gt;&quot; &lt;span class=&quot;category2&quot;&gt;width&lt;/span&gt;=&quot;&lt;span class=&quot;quote&quot;&gt;100%&lt;/span&gt;&quot; &lt;span class=&quot;category2&quot;&gt;maxChars&lt;/span&gt;=&quot;&lt;span class=&quot;quote&quot;&gt;140&lt;/span&gt;&quot;<br />
&nbsp; &nbsp; enter=&quot;&lt;span class=&quot;quote&quot;&gt;setStatus()&lt;/span&gt;&quot; &lt;span class=&quot;category1&quot;&gt;keyUp&lt;/span&gt;=&quot;&lt;span class=&quot;quote&quot;&gt;countCharactersLeft()&lt;/span&gt;&quot; /&amp;gt;&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>When the enter key is pressed, the setStatus method is called:</p>
<p><strong>twitteria_raw/src/MainView.mxml #39-45</strong></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
&lt;span class=&quot;category1&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;function&lt;/span&gt; setStatus():&lt;span class=&quot;category1&quot;&gt;void&lt;/span&gt; {<br />
&nbsp; &nbsp; &lt;span class=&quot;category1&quot;&gt;if&lt;/span&gt; (useDummyData) {<br />
&nbsp; &nbsp; &nbsp; &nbsp; statusSet(&lt;span class=&quot;category1&quot;&gt;null&lt;/span&gt;);<br />
&nbsp; &nbsp; } &lt;span class=&quot;category1&quot;&gt;else&lt;/span&gt; {<br />
&nbsp; &nbsp; &nbsp; &nbsp; twitterService.setStatus(statusText.&lt;span class=&quot;category2&quot;&gt;text&lt;/span&gt;);<br />
&nbsp; &nbsp; }<br />
}&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>Again, this method asks if we&#8217;re using dummy data or not, and calls Twitter if we&#8217;re not. When Twitter returns or the callback is force-called, the callback is executed:</p>
<p><strong>twitteria_raw/src/MainView.mxml #51-55</strong></p>
<div class="acode" style="overflow:auto;padding:10px;">
<div>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;pre&gt;<br />
&lt;span class=&quot;category1&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;category1&quot;&gt;function&lt;/span&gt; statusSet(te:TwitterEvent):&lt;span class=&quot;category1&quot;&gt;void&lt;/span&gt; {<br />
&nbsp; &nbsp; statusText.&lt;span class=&quot;category2&quot;&gt;text&lt;/span&gt; = '&lt;span class=&quot;quote&quot;&gt;&lt;/span&gt;';<br />
&nbsp; &nbsp; countCharactersLeft();<br />
&nbsp; &nbsp; reload();<br />
}&lt;/pre&gt;</div></td></tr></tbody></table></div>
</div>
</div>
<p>The status text and character count are cleaned up, and reload is invoked, which loads the timeline again. With any luck, Twitter will return the status message we just posted in the new timeline.</p>
<p>There it is, a simple, effective, Twitter client.</p>
<p><strong>Next Up</strong></p>
<p>So if what we have here is working, why do we need a framework? Well, the app as it stands has some problems.</p>
<ul>
<li><strong>1.	State Storage.</strong> We&#8217;re passing essential data from view to view, namely the username and password. If Flex&#8217;s binding didn&#8217;t make it so simple to code this, the code it would take on the distinct smell of <a href="http://en.wikipedia.org/wiki/Spaghetti_code" target="_blank">Spaghetti Code</a></li>
<li><strong>2.	Bloated Views.</strong> Look at MainView. Can you describe what its responsibility is? I think it would go something like this: MainView is responsible for keeping a reference to the Twitter service, deciding when to call it or create dummy data, responding when the timeline is loaded, putting the timeline data into a dataprovider, setting status messages, reloading the timeline when a status message is set, and displaying the currently loaded timeline. That&#8217;s way, way, way too much. That view is schizo, friends. It doesn&#8217;t know if it&#8217;s dealing with service interaction, dummy data, display, or a pleasant mix of everything all at once.</li>
</ul>
<p>These problems are exactly the type of thing a good framework will help us address, and we&#8217;re going to start addressing them next time by looking at the old standby Flex Framework, Cairngorm.</p>


<p>Related posts:<ol><li><a href='http://flex.exposedout.net/2009/01/16/frameworkquest-2008-part-4-ioc-with-swiz/' rel='bookmark' title='Permanent Link: FrameworkQuest 2008 Part 4: IoC With Swiz'>FrameworkQuest 2008 Part 4: IoC With Swiz</a></li>
<li><a href='http://flex.exposedout.net/2009/01/16/frameworkquest-2008-part-2-get-control-with-cairngorm/' rel='bookmark' title='Permanent Link: FrameworkQuest 2008 Part 2: Get Control with Cairngorm'>FrameworkQuest 2008 Part 2: Get Control with Cairngorm</a></li>
<li><a href='http://flex.exposedout.net/2009/01/16/frameworkquest-2008-part-5-mate-the-pure-mxml-framework/' rel='bookmark' title='Permanent Link: FrameworkQuest 2008 Part 5: Mate, the Pure MXML Framework'>FrameworkQuest 2008 Part 5: Mate, the Pure MXML Framework</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://flex.exposedout.net/2009/01/16/frameworkquest-2008-introduction/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

