Adobe
Products
Acrobat
Creative Cloud
Creative Suite
Digital Marketing Suite
Digital Publishing Suite
Elements
Photoshop
Touch Apps
Student and Teacher Editions
More products
Solutions
Creative tools for business
Digital marketing
Digital media
Education
Financial services
Government
Web Experience Management
More solutions
Learning Help Downloads Company
Buy
Home use for personal and home office
Education for students, educators, and staff
Business for small and medium businesses
Licensing programs for businesses, schools, and government
Special offers
Search
 
Info Sign in
Welcome,
My cart
My orders My Adobe
My Adobe
My orders
My information
My preferences
My products and services
Sign out
Why sign in? Sign in to manage your account and access trial downloads, product extensions, community areas, and more.
Adobe
Products Sections Buy   Search  
Solutions Company
Help Learning
Sign in Sign out My orders My Adobe
Preorder Estimated Availability Date. Your credit card will not be charged until the product is shipped. Estimated availability date is subject to change. Preorder Estimated Availability Date. Your credit card will not be charged until the product is ready to download. Estimated availability date is subject to change.
Qty:
Purchase requires verification of academic eligibility
Subtotal
Review and Checkout
Adobe Developer Connection / Flex Developer Center /

Developing Flex RIAs with Cairngorm microarchitecture - Part 3: Architecting the view

by Steven Webster

Steven Webster
  • Adobe Consulting
  • www.richinternetapps.com

by Leon Tanner

Leon Tanner
  • Adobe Consulting

Content

  • Architecting the View
  • Binding the Model to the View
  • Best Practices for MXML Development

Modified

23 May 2008

Page tools

Share on Facebook
Share on Twitter
Share on LinkedIn
Bookmark
Print
Flex

Requirements

Prerequisite knowledge

Read Developing Flex RIAs with Cairngorm microarchitecture – Part 1: Introducing Cairngorm before reading this part.

User level

Beginning

Required products

  • Flex Builder 3 (Download trial)

Additional Requirements

Cairngorm version 2.2

  • Download Cairngorm version 2.2

Cairngorm Store

Throughout the series you will find references to code taken from an e-commerce application named Cairngorm Store. You may use this sample application to gain a better understanding of Cairngorm, but please consider it only as a guide. Adobe is not responsible for maintaining the Cairngorm Store application.

  • Download Cairngorm Store (J2EE Container version)
  • Download Cairngorm Store (non J2EE Container version)

Part 2 of this series focused on managing state within rich Internet applications using the Value Object and Model Locator patterns. In Part 3, the aim is to reach out to your application's users. While the concept of holding state on the client empowers developers, it means nothing to users unless they can visualize and interact with that state in a meaningful way. Part 3 continues to demonstrate concepts by example, again using samples from the Cairngorm Store.

The Cairngorm Store displays product images so that users can select products, view further details on them, drag and drop them into their shopping cart, and purchase these products in a checkout process. In this article, we'll explore how to architect the view and deliver rich, immersive experiences to users using the Cairngorm framework. We’ll describe some best practices that you can use to structure your MXML code and files, even though Cairngorm does not prescribe any specific way to structure your view.

  • Part 1: Introducing Cairngorm
  • Part 2: Keeping state on the client
  • Part 3: Architecting the view
  • Part 4: Feature-driven development
  • Part 5: Server-side integration
  • Part 6: Rapid and consistent development with Cairngorm and Flex

Architecting the View

The first and perhaps most important thing to understand about architecting your view logic with Cairngorm is that Cairngorm doesn't actually care how you do it! One key value of the Cairngorm architecture is that it is lightweight and places little imposition on the Flex developer, so as not to stifle individual technical flair.

Rather, Cairngorm offers clear integration points between the "rich" and the "application" in RIA.

The user interface must represent the application's current state by displaying screens and rendering the model in a specific way. This can include showing the products in Cairngorm Store as graphic thumbnails instead of tabular data, deciding which subset of the products to make visible based on a slider that specifies a product price range that the user selects, or recognizing that the user has finished shopping and guiding them to complete the checkout process. You make decisions on the dynamically rendered views by integrating the view with the model. This is done, in part, with Value Objects and the Model Locator pattern; we will discuss the final piece of the puzzle below.

A rich Internet application enables effective communication between the user and the application. The best form of that communication is bidirectional. While the user interface must "speak" to the user by rendering the view according to the state of the model, it must also "listen" to hear what the user wants to do with the application and respond accordingly. In this case, user requests are called gestures. When users click buttons, drag objects, complete and submit forms, and so on, they are gesturing to the application to indicate what they want to do. Responding to user gestures (by listening to the user), doing something on behalf of the user, and then "speaking" back to the user by updating the view (or, more correctly, updating the model, which you might now recognize automatically updates the view) becomes the flow of conversation between user and RIA. Later in this article, we'll explain the Cairngorm design patterns and architecture that can mediate the conversation between user and RIA.

Also in this article, we'll complete the discussion of the Model Locator pattern by explaining how you build the view to take advantage of data binding in the Cairngorm Store.

Next, even though Cairngorm does not prescribe the view, we'll offer some advice on best practices for structuring your view. You can use much of this advice even if you're not using Cairngorm. If you are using Cairngorm, however, heeding this advice will help you make architectural decisions about your MXML components.

In Part 4, we'll introduce you to a "microarchitecture within a microarchitecture," called the Service to Worker concept. Service to Worker is a collaboration of design patterns that the Adobe Consulting team first advocated within Cairngorm as a way to mediate the essential conversation between the user and the application on a feature-by-feature basis.

Binding the Model to the View

Part 2 of this series introduced the Model Locator pattern as a Singleton that can be used to store and retrieve states in your rich Internet application. As much as is appropriate, your application should hold state as Value Objects (VOs) and collections of Value Objects, rather than as primitive types (strings, numbers, and Booleans), which, by comparison, do a poor job of communicating information to fellow application developers.

Now let’s take a more detailed look at the Model Locator strategy, the challenges it can address, and how you can leverage the powerful data binding capabilities of the Flex framework as you work with the Model Locator and Value Object patterns.

When the user selects a product by clicking on it in the summary view, the Cairngorm Store displays detailed product information in a panel, as shown in Figure 1.

Detail view of a product in Cairngorm Store
Figure 1. Detail view of a product in Cairngorm Store
The implementation of the product details component uses data binding to bind the product details that are held in the selectedItem property (type ProductVO) of ShopModelLocator, the Model Locator. The ProductVO is ‘injected’ to this view in the following code:
<details:ProductDetails id="productDetailsComp" width="100%" height="325" selectedItem="{model.selectedItem}" currencyFormatter="{model.currencyFormatter}" />
Drilling down into ProductDetails, note the use of data binding to render the individual elements of the selectedItem instance:
<mx:Script> <![CDATA[[ // set during MXML instantiation public var selectedItem : ProductVO; ]]> </mx:Script> <mx:HBox> <mx:Canvas width="150" height="140" clipContent="false"> <mx:Image id="image" source="{ selectedItem.image }" mouseDown="beginDrag();" mouseOverEffect="big" mouseOutEffect="small" /> </mx:Canvas> <mx:VBox width="100%" height="100%" styleName="productDetailsTitle"> <mx:Label id="name" text="{ selectedItem.name }" styleName="title" /> <mx:Label id="price" text="{ selectedItem.price}" styleName="price" /> </mx:VBox> </mx:HBox> <mx:Text id="description" width="100%" height="100%" text="{ selectedItem.description }"/> </mx:VBox>

With these data bindings in place, any changes to the selectedItem instance held in ShopModelLocator causes the binding to execute in the <details:ProductDetails /> instance, thereby updating the selectedItem attribute of the ProductDetails component. This update causes each binding on selectedItem in ProductDetails to execute, resulting in an update to the image, name, description, and price to reflect the attributes of the newly selected item.

This is the basic premise of Flex data binding. Cairngorm provides an approach for ensuring that dynamic data displayed in your MXML comes from ShopModelLocator, and nowhere else.

The final piece of the puzzle is updating the selectedItem instance in ShopModelLocator. The code below instantiates the two components that are responsible for graphical and textual rendering of the entire product list. In the Cairngorm Store application, a ViewStack navigator container determines which one is shown at any one time.

<mx:Script> <![CDATA[ [Bindable] public var selectedItem:ProductVO; ]]> </mx:Script> <mx:Canvas clipContent="false" width="150" height="140"> <mx:Image id="image" source="{ selectedItem.image }" mouseDown="beginDrag( event );" rollOverEffect="zoom" rollOutEffect="zoomOut"/> </mx:Canvas> <mx:VBox width="100%" height="100%" styleName="productDetailsTitle"> <mx:Label id="itemName" text="{ selectedItem.name }" styleName="title" /> <mx:Label id="price" text="{ currencyFormatter.format( selectedItem.price ) }" styleName="price" /> </mx:VBox> <mx:Text id="description" width="100%" height="100%" text="{ selectedItem.description }"/>

Both components expose select events, which the components dispatch when the user clicks a new product. To handle these events, as shown in the highlighted code above, the code simply updates the selectedItem instance on ShopModelLocator to a ProductVO value object representing the item that the user has just selected.

Because the model notifies the view of this change through data binding, the application developer does not need to worry about implementing the view or updating the many different elements of the view to reflect the model change.

The GraphicalProductList and TextualProductList components provide an example of the "single model, multiple view" strategy. In their instantiation, both of these components bind their individual products attributes to the same model, ShopModelLocator.products. The products property is an ArrayCollection of ProductVOs, as you may recall from Part 2.

In the GraphicalProductList component, this list of products becomes the dataProvider for a TileList, which has its own item renderer (ProductThumbnail) capable of parsing and rendering data from a ProductVO:

<mx:TileList id="tileListComp" width="100%" height="100%" dataProvider="{ products }" itemRenderer="com.adobe.cairngorm.samples.store.view.productview.ProductThumbnail" change="updateSelectedProduct( event );" />
Meanwhile, the TextualProductList component does nothing more than assign the list of ProductVOs to the dataProvider of a DataGrid, which renders the list of ProductVO instances accordingly:
<mx:DataGrid id="dataGridComp" dataProvider="{ products }" change="updateSelectedProduct( event );" dragEnabled="true" width="100%" height="100%"> <mx:columns> <mx:Array> <mx:DataGridColumn dataField="name" headerText="Name" width="300" /> <mx:DataGridColumn dataField="price" labelFunction="format" headerText="Price" textAlign="right" /> </mx:Array> </mx:columns> </mx:DataGrid>
This example demonstrates the Model Locator strategy in action. Each view component declares and renders its own local model or property and each waits for its data or model to be ‘injected’ from a parent, therefore each is completely oblivious to the application running within a Cairngorm architecture. Only at the very highest level of the component's usage—most often in the entry point MXML file—do you couple the component's usage to Cairngorm by populating and binding its local model to a model residing on ShopModelLocator.

Best Practices for MXML Development

The preceding discussion touches on best practices that Adobe Consulting urges developers to adopt when implementing their own user experiences with MXML.

One key best practice is "to develop with components in mind." With MXML, it is incredibly easy to create components that extend base tags with application-specific functionality. If you have ever had to review someone else's MXML code and tried to trace your way through hierarchies of VBox controls containing HBox controls containing VBox controls containing TileList controls containing VBox controls, and so forth, you will quickly realize the value in creating components that have semantic meaning.

If you review the Cairngorm Store's code, you will quickly be able to cross-reference MXML components with their visual renderings on the screen. By creating components such as Main, SideArea, ProductDetails, ShoppingCart, ProductDetails, ProductThumbnail, GraphicalProductList, TextualProductList, ProductAndCheckoutViewStack, and so forth, you will be able to navigate your own source code more easily, never mind someone else's code.

When designing with components in mind, learn to use the events infrastructure within Flex to couple your components loosely. For instance, create your own events, which describe what happens at the user level, not at the Flex framework level. Consider the difference between a button within a VBox control having some code within a click="" event handler, versus a component called ShoppingCart that responds to an event called productAdded. When you create your own events, broadcast these events from within your components and handle these events accordingly. Your code base will become much more maintainable.

Again, consider the ProductDetails component in the Cairngorm Store, which is an application-specific rendering of a Panel component that broadcasts an event whenever the user clicks the Add to Cart button:

<mx:Panel xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:details="com.adobe.cairngorm.samples.store.view.productdetails.*" title="Product Details" styleName="productDetails"> <mx:Metadata> [Event(name="addProduct", type="com.adobe.cairngorm.samples.store.event.AddProductEvent")] </mx:Metadata> <mx:Script> <![CDATA[ import com.adobe.cairngorm.samples.store.vo.ProductVO; import com.adobe.cairngorm.samples.store.event.AddProductEvent; public function addProductToShoppingCart() : void { var event:AddProductEvent = new AddProductEvent(); event.product = selectedItem; event.quantity = numericStepperComp.value; dispatchEvent( event ); } : : : <mx:Button label="Add to Cart" click="addProductToShoppingCart();" /> </mx:Panel>

Here the click event of the button generates an addProduct event out of the component. Furthermore, the event includes the selectedItem (the product to add) and the quantity attribute associated with it on the ProductDetails component, which represents how much of the product the user wishes to add to the shopping cart.

Although this advice is in no way specific to Cairngorm application development, following these best practices for MXML development improves the clarity of your application code and makes it easier for you to recognize integration points between your MXML and ActionScript implementations of the view, as well as with any underlying business logic applied throughout the Cairngorm skeleton.

Where to Go from Here

When developing an enterprise RIA, it is important to understand how to construct a view using the building blocks of MXML and ActionScript. Equally important is understanding how you can build this view on the underlying architecture of the Cairngorm skeleton.

In this series of articles, you have seen how to manage client-side state using the Model Locator and Value Object patterns. Although we've given some guidance and best practices to consider when architecting your view, Cairngorm makes no assumptions and imposes no restrictions on how you choose to architect your view.

Now that you have a better idea of how to implement the view and keep state on the view, it is time to look at how to implement features with the addition of business logic within commands—the "application" in rich Internet application. We cover that topic in Part 4.

Developing Flex RIAs with Cairngorm microarchitecture – Part 4: Feature-Driven Development

Tutorials & Samples

Tutorials

  • Flex mobile performance checklist
  • Flex and Maven with Flexmojos – Part 3: Journeyman
  • Migrating Flex 3 applications to Flex 4.5 – Part 4

Samples

  • Twitter Trends
  • Flex 4.5 reference applications
  • Mobile Trader Flex app on Android Market

Flex User Forum

More
07/25/2011 Flash Player Debug Issues - Safari 5.1 & Chrome 13
04/22/2012 Loader png - wrong color values in BitmapData
04/22/2012 HTTPService and crossdomain.xml doesn't work as expected
04/23/2012 Memory related crashes in Flex application

Flex Cookbook

More
04/06/2012 How to detect screen resize with a SkinnableComponent
02/29/2012 Embed Stage3D content inside Flex application components
02/15/2012 Custom WorkFlow Component
02/09/2012 Using Camera with a MediaContainer instead of VideoDisplay

Products

  • Acrobat
  • Creative Cloud
  • Creative Suite
  • Digital Marketing Suite
  • Digital Publishing Suite
  • Elements
  • Mobile Apps
  • Photoshop
  • Touch Apps
  • Student and Teacher Editions

Solutions

  • Digital marketing
  • Digital media
  • Web Experience Management

Industries

  • Education
  • Financial services
  • Government

Help

  • Product help centers
  • Orders and returns
  • Downloading and installing
  • My Adobe

Learning

  • Adobe Developer Connection
  • Adobe TV
  • Training and certification
  • Forums
  • Design Center

Ways to buy

  • For personal and home office
  • For students, educators, and staff
  • For small and medium businesses
  • For businesses, schools, and government
  • Special offers

Downloads

  • Adobe Reader
  • Adobe Flash Player
  • Adobe AIR
  • Adobe Shockwave Player

Company

  • News room
  • Partner programs
  • Corporate social responsibility
  • Career opportunities
  • Investor Relations
  • Events
  • Legal
  • Security
  • Contact Adobe
Choose your region United States (Change)
Choose your region Close

North America

Europe, Middle East and Africa

Asia Pacific

  • Canada - English
  • Canada - Français
  • Latinoamérica
  • México
  • United States

South America

  • Brasil
  • Africa - English
  • Österreich - Deutsch
  • Belgium - English
  • Belgique - Français
  • België - Nederlands
  • България
  • Hrvatska
  • Česká republika
  • Danmark
  • Eastern Europe - English
  • Eesti
  • Suomi
  • France
  • Deutschland
  • Magyarország
  • Ireland
  • Israel - English
  • ישראל - עברית
  • Italia
  • Latvija
  • Lietuva
  • Luxembourg - Deutsch
  • Luxembourg - English
  • Luxembourg - Français
  • الشرق الأوسط وشمال أفريقيا - اللغة العربية
  • Middle East and North Africa - English
  • Moyen-Orient et Afrique du Nord - Français
  • Nederland
  • Norge
  • Polska
  • Portugal
  • România
  • Россия
  • Srbija
  • Slovensko
  • Slovenija
  • España
  • Sverige
  • Schweiz - Deutsch
  • Suisse - Français
  • Svizzera - Italiano
  • Türkiye
  • Україна
  • United Kingdom
  • Australia
  • 中国
  • 中國香港特別行政區
  • Hong Kong S.A.R. of China
  • India - English
  • 日本
  • 한국
  • New Zealand
  • 台灣

Southeast Asia

  • Includes Indonesia, Malaysia, Philippines, Singapore, Thailand, and Vietnam - English

Copyright © 2012 Adobe Systems Incorporated. All rights reserved.

Terms of Use | Privacy Policy and Cookies (Updated)

Ad Choices

Reviewed by TRUSTe: site privacy statement