Home  >  Development  >  features

Anatomy of an Enterprise Flex RIA Part 18: Building the View

AddThis Social Bookmark Button

Last installment we looked at testing flex and automating the tests. Now we're going to dive back in to creating he Flex view.

The view of Bookie, as released in the sample code, is nothing special to look at; I’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.

series18_figure22.jpg
Figure 22. The files containing the Bookie application’s view

User Section: The Login Process

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.

series18_figure23.jpg
Figure 23. The login process

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

<business:Services id="bookieServices" />
<control:BookieController id="bookieController" />

Around line 38 is where we set up Cairngorm. We’ve already looked at services. The controller, BookieController, is where we map all the commands to events, and we’ll see an example of that soon.

<mx:Application
    ...
    currentState="{model.currentState}"
>

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’ll remember, defaults to the SIGNED_OUT constant on the model. In the following code snippet, you’ll notice that the name of the “login screen” 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’s binding mechanism will watch for those changes and set the currentState on the application to that new state.

Let’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’s state programmatically or automatically, which is easier than changing and then managing all the properties in code you have to write.

<mx:states>
    <mx:State name="{BookieModel.SIGNED_OUT}">
         <mx:AddChild>
              <view:SignInPanel id="signInPanel" horizontalAlign="center" verticalAlign="middle" />
         </mx:AddChild>
    </mx:State>

Looking farther down the file to around line 47, you’ll see the beginning of a 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’s card number and starts the sign-in process when the user clicks a button.

<mx:Panel ...>
    ...
    <mx:Script>
    ...
    [Bindable]
    private var model:BookieModel =
                   BookieModel.getInstance();
    ...
    </mx:Script>

    <mx:Label text="Library Card Number" />
    <mx:TextInput id="cardNumber" enter="signIn()" />
    <mx:Button id="signInButton" label="Sign In" click="signIn()" />
    <mx:Text text="{model.loginFailedMessage}" color="0xFF0000" />
</mx:Panel>

Again, we’re using binding to set the message to show whether the login fails. If there’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.

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.

Next, notice that pressing Enter in the cardNumber field or clicking the signInButton calls the signIn method:

private function signIn():void {
     new SignInEvent(cardNumber.text).dispatch();
     cardNumber.text = "";
}

This is our first look at a Cairngorm event in the wild. Let’s follow it all the way back to see what happens.

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:

public class BookieController extends FrontController {
 
     public function BookieController()    {
  
           addCommand(SignInEvent.SignIn_Event, SignInCommand)
      ...

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’s registered to. The command mapped to the SignInEvent.SignIn_Event string constant is the SignInCommand, which you’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.

Once the service returns, it calls the result method on the SignInCommand:

...
    public function result(result:Object):void {
          if (result.result != null) {
               var p:Person = Person(result.result);
               model.user = p;
               model.loginFailedMessage = "";
  
               model.currentState = BookieModel.SIGNED_IN;
           } else {
               model.loginFailedMessage = "That card number was not found";
           }
 
     }
...

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.

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.

This series of interactions between the different systems we’ve been exploring is pretty standard in a Flex/Cairngorm/LCDS/Java application. Understand the parts of this one interaction, and you’re we’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.

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 here.

Comments

4 Comments

Forrest said:

really cool things

ashok said:

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.

Wanted

ashok said:

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.

Can anybody reading this, please advise on what could be wrong here.

sbick said:

new SignInEvent(cardNumber.text).dispatch();

UM has a very hard to find note about self dispatching Events.

From inside the UMEvent class:

*

Deprecated, Do not use! The default UMEvent bubbling and FrontController event hooks obviate this method.


* This method also completely distorts the event structures within Flex... no other events in Flex can dispatch themselves.
* Events are "announcements" with optional data packaged in the announcement. Events are passive. NOT active.
*
* Dispatch this event via the Cairngorm event dispatcher.
*/
override public function dispatch() : Boolean
{
return CairngormEventDispatcher.getInstance().dispatchEvent( this );
}

Leave a comment


Type the characters you see in the picture above.

Poll: ECMAScript Reaction

The ECMA organization recently decided to stop work on ECMAScript 4 and begin a new version, tentatively described as ES "Harmony." How would you like to see this affect the evolution of ActionScript?

Vote | View Poll Results | Read Related Blog Entry

Tag Cloud

Related Books

Development Series

Get an overview of the tools and technologies that work together to allow developers to build Rich Internet Applications (RIAs) quickly and easily.

Anatomy of an Enterprise Flex RIA

Archives


 
 


Or, visit our complete archive.  

About This Site

Welcome to the premiere community site for all things RIA sponsored by O'Reilly Media and Adobe Systems Incorporated.

About Us
Meet the Experts
Meet Our Contributors
Send Us Feedback