<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" 
      xmlns:thr="http://purl.org/syndication/thread/1.0">
  <link rel="alternate" type="text/html" href="http://www.insideria.com/2008/05/anatomy-of-an-enterprise-flex-11.html" />
  <link rel="self" type="application/atom+xml" href="http://www.insideria.com/atom.xml" />
  <id>tag:www.insideria.com,2009://34/tag:www.insideria.com,2008://34.23753-</id>
  <updated>2009-11-16T15:43:40Z</updated>
  <title>Comments for Anatomy of an Enterprise Flex RIA Part 18: Building the View (http://www.insideria.com/2008/05/anatomy-of-an-enterprise-flex-11.html)</title>
  <generator uri="http://www.sixapart.com/movabletype/">Movable Type 4.21-en</generator>
  <entry>
    <id>tag:www.insideria.com,2008://34.23753</id>
    <link rel="alternate" type="text/html" href="http://www.insideria.com/2008/05/anatomy-of-an-enterprise-flex-11.html" />
    <link rel="service.edit" type="application/atom+xml" href="http://blogs.oreilly.com/cgi-bin/mt/mt-atom.cgi/weblog/blog_id=34/entry_id=23753" title="Anatomy of an Enterprise Flex RIA Part 18: Building the View" />
    <published>2008-05-19T17:56:33Z</published>
    <updated>2008-10-01T00:20:07Z</updated>
    <title>Anatomy of an Enterprise Flex RIA Part 18: Building the View</title>
    <summary>In this installment of Anatomy of an Enterprise Flex RIA we&apos;re going to continue building the Flex view. We&apos;ll see more of mxml, Flex&apos;s layout language, and Flex&apos;s powerful binding framework.</summary>
    <author>
      <name>Tony Hillerson</name>
      
    </author>
    
    <category term="Features" />
    
    <content type="html" xml:lang="en" xml:base="http://www.insideria.com/">
      <![CDATA[<p> Last installment we looked at testing flex and automating the tests. Now we're going to dive back in to creating he Flex view.</p>
<p>The view of Bookie, as released in the sample code, is nothing special to look at; I&#8217;m not a designer, and anyhow, I want the focus to be on following the interactions from the frontend to the backend. Figure 22 shows the files containing the view of the application.</p>

<div class="ap_c" ><a href="http://www.insideria.com/upload/2008/05/anatomy_of_an_enterprise_flex/series18_figure22.jpg" class="highslide" onclick="return hs.expand(this)"><img src="http://www.insideria.com/upload/2008/05/anatomy_of_an_enterprise_flex/series18_figure22.jpg" alt="series18_figure22.jpg" title="Click to enlarge" width="400"/></a><div class="apcaption">Figure 22. The files containing the Bookie application&#8217;s view </div></div>

<p><strong>User Section: The Login Process</strong></p>
<p>The login process is the first interaction in the user section of the application, and it actually showcases a lot of important features and interactions both in Flex and between Flex and the service layer, as shown in Figure 23.</p>

<div class="ap_c" ><a href="http://www.insideria.com/upload/2008/05/anatomy_of_an_enterprise_flex/series18_figure23.jpg" class="highslide" onclick="return hs.expand(this)"><img src="http://www.insideria.com/upload/2008/05/anatomy_of_an_enterprise_flex/series18_figure23.jpg" alt="series18_figure23.jpg" title="Click to enlarge" width="400"/></a><div class="apcaption">Figure 23. The login process</div></div>

<p>Let&#8217;s look at the whole process to see what&#8217;s going on here. If we look in the root application file for the user part of Bookie, index.mxml, we&#8217;ll see a few important things for the first time:</p>

<div class="acode" style="overflow: auto; padding: 10px; height: 18px;" ><div style="overflow-x: visible;">
<code language="perl">
<pre>
&lt;business:Services id="<span class="quote">bookieServices</span>" /&gt;
&lt;control:BookieController id="<span class="quote">bookieController</span>" /&gt;</pre>
</code>

</div></div>

<p>Around line 38 is where we set up Cairngorm. We&#8217;ve already looked at services. The controller, BookieController, is where we map all the commands to events, and we&#8217;ll see an example of that soon.</p>

<div class="acode" style="overflow: auto; padding: 10px; height: 30px;" ><div style="overflow-x: visible;">
<code language="perl">
<pre>
&lt;mx:<span class="category2">Application</span>
    ...
    currentState="<span class="quote">{model.currentState}</span>"
&gt;</pre>
</code>

</div></div>

<div class="ap_r" style="width:180px;"><a href="http://www.oreilly.com/catalog/9780596514402/?CMP=ILC-dm_nav_related-books" target="_blank"><img border="0" src="http://www.oreilly.com/catalog/covers/9780596514402_cat.gif" width="180" height="233" /></a>
<div class="apcaption"><a href="http://www.oreilly.com/catalog/9780596514402/?CMP=ILC-dm_nav_related-books" target="_blank">Get your copy of Tony Hillerson's Enterprise Application Development with Flex.</a></div></div>

<p>Next, notice that in the root application tag the currentState is set to a bound variable on the model, called currentState. This sets the starting state for the application to whatever is initialized on the model, which, if you&#8217;ll remember, defaults to the SIGNED_OUT constant on the model. In the following code snippet, you&#8217;ll notice that the name of the &#8220;login screen&#8221; state is set to that constant on the model. This way, anywhere you need to change the state of the view in the application, you can set the currentState on the model to one of the state constants we set up earlier, and Flex&#8217;s binding mechanism will watch for those changes and set the currentState on the application to that new state.</p>

<p>Let&#8217;s talk a little bit about states in Flex. A Flex component can make use of states to group sets of properties and other children components. Developers can then use ActionScript or the binding framework to change the component&#8217;s state programmatically or automatically, which is easier than changing and then managing all the properties in code you have to write.</p>

<div class="acode" style="overflow: auto; padding: 10px; height: 50px;" ><div style="overflow-x: visible;">
<code language="perl">
<pre>
&lt;mx:states&gt;
    &lt;mx:State <span class="category2">name</span>="<span class="quote">{BookieModel.SIGNED_OUT}</span>"&gt;
         &lt;mx:AddChild&gt;
              &lt;view:SignInPanel id="<span class="quote">signInPanel</span>" horizontalAlign="<span class="quote">center</span>" verticalAlign="<span class="quote">middle</span>" /&gt;
         &lt;/mx:AddChild&gt;
    &lt;/mx:State&gt;</pre>
</code>

</div></div>

<p>Looking farther down the file to around line 47, you&#8217;ll see the beginning of a <states> tag. This sets up an array of states in the states property of the application. The first state in the collection, which is also the starting state, signInScreen, simply adds a SignInPanel centered on the view. SignInPanel is a simple panel that takes the user&#8217;s card number and starts the sign-in process when the user clicks a button.</p>

<div class="acode" style="overflow: auto; padding: 10px; height: 90px;" ><div style="overflow-x: visible;">
<code language="perl">
<pre>
&lt;mx:Panel ...&gt;
    ...
    &lt;mx:Script&gt;
    ...
    [Bindable]
    <span class="category1">private</span> <span class="category1">var</span> model:BookieModel =
                   BookieModel.getInstance();
    ...
    &lt;/mx:Script&gt;

    &lt;mx:Label <span class="category2">text</span>="<span class="quote">Library Card Number</span>" /&gt;
    &lt;mx:TextInput id="<span class="quote">cardNumber</span>" enter="<span class="quote">signIn()</span>" /&gt;
    &lt;mx:<span class="category2">Button</span> id="<span class="quote">signInButton</span>" <span class="category1">label</span>="<span class="quote">Sign In</span>" click="<span class="quote">signIn()</span>" /&gt;
    &lt;mx:Text <span class="category2">text</span>="<span class="quote">{model.loginFailedMessage}</span>" <span class="category2">color</span>="<span class="quote">0xFF0000</span>" /&gt;
&lt;/mx:Panel&gt;</pre>
</code>

</div></div>

<p>Again, we&#8217;re using binding to set the message to show whether the login fails. If there&#8217;s a problem in the sign-in process, all we need to do is set the loginFailedMessage property on the model from anywhere and the Text control on the SignIn panel will display that message.</p>

<p>This is another example of the kind of thing that makes Flex such a great choice for rapid application development. All the glue code to get that value updated on the login screen is baked into Flex.</p>
<p>Next, notice that pressing Enter in the cardNumber field or clicking the signInButton calls the signIn method:</p>

<div class="acode" style="overflow: auto; padding: 10px; height: 30px;" ><div style="overflow-x: visible;">
<code language="perl">
<pre>
<span class="category1">private</span> <span class="category1">function</span> signIn():<span class="category1">void</span> {
     <span class="category1">new</span> SignInEvent(cardNumber.<span class="category2">text</span>).dispatch();
     cardNumber.<span class="category2">text</span> = "<span class="quote"></span>";
}</pre>
</code>

</div></div>

<p>This is our first look at a Cairngorm event in the wild. Let&#8217;s follow it all the way back to see what happens. </p>

<p>First the event is matched to a command by the controller, BookieController. Looking in that class can tell us which command maps to that event:</p>

<div class="acode" style="overflow: auto; padding: 10px; height: 50px;" ><div style="overflow-x: visible;">
<code language="perl">
<pre>
<span class="category1">public</span> <span class="category1">class</span> BookieController <span class="category1">extends</span> FrontController {
 
     <span class="category1">public</span> <span class="category1">function</span> BookieController()    {
  
           addCommand(SignInEvent.SignIn_Event, SignInCommand)
      ...</pre>
</code>

</div></div>

<p>An instance of CairngormEvent, such as SignInEvent, is constructed and dispatched. The event has been registered to a command and knows how to tell the CairngormEventDispatcher to look up the command it&#8217;s registered to. The command mapped to the SignInEvent.SignIn_Event string constant is the SignInCommand, which you&#8217;ll remember calls BookieDelegate.findPersonByCardNumber, which calls the same method on the BookSearchService POJO in Java-land. The search service looks for a user with that card number through PersonDAOBean.findByCardNumber. If it finds a person it returns it; otherwise, it returns null.</p>

<p>Once the service returns, it calls the result method on the SignInCommand:</p>

<div class="acode" style="overflow: auto; padding: 10px; height: 90px;" ><div style="overflow-x: visible;">
<code language="perl">
<pre>
...
    <span class="category1">public</span> <span class="category1">function</span> result(result:<span class="category2">Object</span>):<span class="category1">void</span> {
          <span class="category1">if</span> (result.result != <span class="category1">null</span>) {
               <span class="category1">var</span> p:Person = Person(result.result);
               model.user = p;
               model.loginFailedMessage = "<span class="quote"></span>";
  
               model.currentState = BookieModel.SIGNED_IN;
           } <span class="category1">else</span> {
               model.loginFailedMessage = "<span class="quote">That card number was not found</span>";
           }
 
     }
...</pre>
</code>

</div></div>

<p>result decides whether a person was found (if result.result was not null). If the result was null it changes the loginFailedMessage on the model; if not, it sets the currentState on the model to the SIGNED_IN constant, which propagates through binding to the current state of the application file, index.mxml.</p>
<p>Well, there you have it, the full round trip of a user interaction from a click on a button to a Cairngorm command to LCDS to the Java service to the database and back through LCDS to that same command which manipulates the original view by changing a variable on the model, which propagates to the view via binding.</p>

<p>This series of interactions between the different systems we&#8217;ve been exploring is pretty standard in a Flex/Cairngorm/LCDS/Java application. Understand the parts of this one interaction, and you&#8217;re we&#8217;ll on your way to understanding how to best build RIAs that are flexible, loosely coupled, and built with small, easy-to-understand parts that have a clear responsibility.</p>

<p>The next installment will look at the search process of the application, and its view and service interaction. You can always find the entire series <a href="http://www.insideria.com/series-anatomy-flex.html">here</a>.</p>]]>
      
    </content>
  </entry>

  <entry>
    <id>tag:www.insideria.com,2008://34.23753-comment:2017250</id>
    <thr:in-reply-to ref="tag:www.insideria.com,2008://34.23753" type="text/html" href="http://www.insideria.com/2008/05/anatomy-of-an-enterprise-flex-11.html"/>
    <link rel="alternate" type="text/html" href="http://www.insideria.com/2008/05/anatomy-of-an-enterprise-flex-11.html#comment-2017250" />
    <title>Comment from Forrest on 2008-05-20</title>
    <author>
        <name>Forrest</name>
        <uri>http://www.ideafarm.cn</uri>
    </author>
    <content type="html" xml:lang="en" xml:base="http://www.ideafarm.cn">
        <![CDATA[<p>really cool things</p>]]>
    </content>
    <published>2008-05-20T09:59:55Z</published>
  </entry>

  <entry>
    <id>tag:www.insideria.com,2008://34.23753-comment:2017365</id>
    <thr:in-reply-to ref="tag:www.insideria.com,2008://34.23753" type="text/html" href="http://www.insideria.com/2008/05/anatomy-of-an-enterprise-flex-11.html"/>
    <link rel="alternate" type="text/html" href="http://www.insideria.com/2008/05/anatomy-of-an-enterprise-flex-11.html#comment-2017365" />
    <title>Comment from ashok on 2008-05-27</title>
    <author>
        <name>ashok</name>
        <uri></uri>
    </author>
    <content type="html" xml:lang="en" xml:base="">
        <![CDATA[<p>I have followed exactly the same method in my application, but do not see any chnage in state. I debugged the application and the event does get propogated, through the command, and returns the result in a E4X format, and comes back to the login screen.I changed the current state in the resut method of my command. This works partially and my inital login screen does change but i see a blank after the login screen fadesout. Can anybody reading this, please advise on what could be wring here. </p>

<p>Wanted</p>]]>
    </content>
    <published>2008-05-27T08:17:46Z</published>
  </entry>

  <entry>
    <id>tag:www.insideria.com,2008://34.23753-comment:2017366</id>
    <thr:in-reply-to ref="tag:www.insideria.com,2008://34.23753" type="text/html" href="http://www.insideria.com/2008/05/anatomy-of-an-enterprise-flex-11.html"/>
    <link rel="alternate" type="text/html" href="http://www.insideria.com/2008/05/anatomy-of-an-enterprise-flex-11.html#comment-2017366" />
    <title>Comment from ashok on 2008-05-27</title>
    <author>
        <name>ashok</name>
        <uri></uri>
    </author>
    <content type="html" xml:lang="en" xml:base="">
        <![CDATA[<p>I have followed exactly the same method in my application, but do not see any change in state. I debugged the application and the event does get propogated, through the command, and returns the result in a E4X format, and comes back to the login screen.I changed the current state in the resut method of my command. This works partially and my inital login screen does change but i see a blank after the login screen fadesout, i.e my second states components are not visible. The second state has a number of child components.</p>

<p>Can anybody reading this, please advise on what could be wrong here.</p>]]>
    </content>
    <published>2008-05-27T08:19:47Z</published>
  </entry>

  <entry>
    <id>tag:www.insideria.com,2008://34.23753-comment:2018923</id>
    <thr:in-reply-to ref="tag:www.insideria.com,2008://34.23753" type="text/html" href="http://www.insideria.com/2008/05/anatomy-of-an-enterprise-flex-11.html"/>
    <link rel="alternate" type="text/html" href="http://www.insideria.com/2008/05/anatomy-of-an-enterprise-flex-11.html#comment-2018923" />
    <title>Comment from sbick on 2008-07-16</title>
    <author>
        <name>sbick</name>
        <uri></uri>
    </author>
    <content type="html" xml:lang="en" xml:base="">
        <![CDATA[<p>new SignInEvent(cardNumber.text).dispatch();</p>

<p>UM has a very hard to find note about self dispatching Events.</p>

<p>From inside the UMEvent class:</p>

<p>     * <p><strong>Deprecated, Do not use! The default UMEvent bubbling and FrontController event hooks obviate this method.</strong></p><br />
       * This method also completely distorts the event structures within Flex... no other events in Flex can dispatch themselves.<br />
       * Events are "announcements" with optional data packaged in the announcement. Events are passive. NOT active.<br />
       *  <br />
       * Dispatch this event via the Cairngorm event dispatcher.<br />
       */<br />
      override public function dispatch() : Boolean<br />
      {<br />
         return CairngormEventDispatcher.getInstance().dispatchEvent( this );<br />
      }   </p>]]>
    </content>
    <published>2008-07-17T02:18:30Z</published>
  </entry>

</feed
