10 things a good flex developer should know

69
10 Things A Good Flex Developer Should Know Posted by Jeremy Mitchell It takes more to be a good Flex programmer than simply knowing how to use some built-in Flex containers and controls . It takes significantly more. Here's my take on the subject...along with some resources or some keywords that you can easily Google. 1. Object-oriented programming (OOP) The language on which Flex is based, ActionScript 3, is a fully object- oriented language. Although not an easy concept to grasp, object-oriented programming is a prerequisite to learning Flex. If your prior experience includes OOP (Java, C#, Ruby, etc), then you're set. If not, you'll need to pick up an OOP book and start learning ASAP. Head First Java (Java? Yes, I know. But trust me.) Object-oriented programming with ActionScript 3.0 Note: Some of you may be asking - "What about design patterns?". Let's take one step at a time, shall we? Concern yourself with understanding classes and objects, interfaces, inheritance, composition, polymorphism, encapsulation, etc. Only then should you even consider looking at design patterns. In fact, if I write a post entitled "10 Things A GREAT Flex Developer Should Know", design patterns will be 1st on the list. 2. ActionScript / MXML ActionScript is the programming language used along with MXML to create Flex applications. MXML is tag-based declarative language written in XML. Each MXML tag is mapped directly to a corresponding ActionScript class. MXML is primarily used by Flex developers to lay out the UI, whereas, ActionScript is used for business logic. Exceptions apply, of course. The Flex Framework includes hundreds of ActionScript classes and interfaces used to develop Flex applications. Your skill level as a Flex developer is tied directly to your proficiency with ActionScript and MXML. Flex in a Week Tour De Flex Essential ActionScript 3.0 Note: You should be VERY familiar with the Flex Language Reference . As a Flex developer, you will use it on a daily basis. 3. Debugging

Upload: naveen-kumar

Post on 19-Nov-2014

113 views

Category:

Documents


2 download

TRANSCRIPT

Page 1: 10 Things a Good Flex Developer Should Know

10 Things A Good Flex Developer Should Know

Posted by Jeremy Mitchell It takes more to be a good Flex programmer than simply knowing how to use some built-in Flex containers and controls. It takes significantly more.

Here's my take on the subject...along with some resources or some keywords that you can easily Google.

1. Object-oriented programming (OOP)

The language on which Flex is based, ActionScript 3, is a fully object-oriented language. Although not an easy concept to grasp, object-oriented programming is a prerequisite to learning Flex. If your prior experience includes OOP (Java, C#, Ruby, etc), then you're set. If not, you'll need to pick up an OOP book and start learning ASAP.

Head First Java (Java? Yes, I know. But trust me.) Object-oriented programming with ActionScript 3.0

Note: Some of you may be asking - "What about design patterns?". Let's take one step at a time, shall we? Concern yourself with understanding classes and objects, interfaces, inheritance, composition, polymorphism, encapsulation, etc. Only then should you even consider looking at design patterns. In fact, if I write a post entitled "10 Things A GREAT Flex Developer Should Know", design patterns will be 1st on the list.

2. ActionScript / MXML

ActionScript is the programming language used along with MXML to create Flex applications. MXML is tag-based declarative language written in XML. Each MXML tag is mapped directly to a corresponding ActionScript class. MXML is primarily used by Flex developers to lay out the UI, whereas, ActionScript is used for business logic. Exceptions apply, of course.

The Flex Framework includes hundreds of ActionScript classes and interfaces used to develop Flex applications. Your skill level as a Flex developer is tied directly to your proficiency with ActionScript and MXML.

Flex in a Week Tour De Flex Essential ActionScript 3.0

Note: You should be VERY familiar with the Flex Language Reference. As a Flex developer, you will use it on a daily basis.

3. Debugging

A large portion of any developer's time is spent debugging. Obviously, debugging is required to track down the root cause of bugs. However, debugging is also a great way to learn a new code base.

Fortunately, there are many tools available to assist you with your debugging efforts. Invest some time in learning these tools. Your investment will pay dividends immediately.

Flash Builder 4 Debugger De MonsterDebugger Kap Inspect

4. Event-driven programming

Page 2: 10 Things a Good Flex Developer Should Know

Flex applications are event-driven. Every action is the result of an asynchronous event.

As a Flex developer, you must know how to respond to events and how to create and dispatch events. To accomplish this, a solid understanding of Flex's event architecture is required including familiarity with the following concepts:

Built-in events (Flash Player or Flex Framework events) Custom events (Events created by the developer that extend the Event class or one of its subclasses) Event dispatchers, event broadcasters (See EventDispatcher class and its dispatchEvent method) Event listeners, event handlers (See EventDispatcher class and its addEventListener &

removeEventListener methods) Event Flow (capture, target & bubbling phases; target vs. currentTarget) Event objects, event types (See Event class and subclasses) Event default behavior (See Event class and subclasses and its preventDefault method)

5. Data binding

On the surface, data binding is a no brainer. Bind the value of one property to the value of another property using curly bracket notation. When the value of the source property changes, so does the value of the property.

However, there is overhead associated with data binding and indiscriminate use can have performance implications. A solid understanding of data binding will help you determine when it is appropriate and when it is not.

Flex Tips - Using Bindable Metadata Events Michael Labriola's presentation entitled Diving in the Data Binding Waters

6. Item renderers

One characteristic of a well-designed Flex application is the presentation of data in a visually-compelling manner. Flex provides a number of list-based controls (DataGrid, List, TileList, HorizontalList, etc) responsible for the presentation of data. However, only with the help of an item renderer can a list-based control customize the display of the data. You will spend a lot of time working with item renderers. Get very comfortable with how they work.

Flex Examples - Item Renderers in Practice A Deep Dive into Flex 4 Lists and Layouts

7. Accessing remote data

Do you know of many applications that don't interact with data? Me neither. Learn how to retrieve data via HTTPService, WebService and RemoteObject. A Flex architecture framework may also help you with this (see #9).

Retrieving and handling data with HTTPService Retrieving and handling data with WebService Retrieving and handling data with RemoteObject

8. Styling / Skinning

Let's not forget that Flex is a UI technology and as such certain design expectations exist. As a Flex developer, you should be able to customize the look and feel of your Flex applications using CSS styling and/or graphical or programmatic skins.

Page 3: 10 Things a Good Flex Developer Should Know

With Flex 4, there are no more excuses. Spend a little time getting to know the right side of your brain for once. It's a nice change of pace, and it will help differentiate yourself from other Flex developers.

Flex Style Explorer ScaleNine Introduction to Flex: Part 3 - Styles & Skins

9. At least one Flex architecture framework

Most Flex architecture frameworks enforce a separation of concerns by implementing an MVC (model-view-controller) application design. In addition, many of these same frameworks dictate how your code should be organized and packaged within your Flex project.

Although many would argue that frameworks are unnecessary, I believe that Flex developers benefit in many ways from the experience of using one. Simply witnessing the techniques (good or bad) employed by a framework to solve complex architectural issues contributes to your growth as a Flex developer / architect.

Also, it's hard to deny the fact that framework experience will substantially increase your marketability as a Flex developer. Jesse Warden recently told me "There are a few shops that don't use frameworks, but those are rare. It's in 'fashion' whether we like it or not." I agree.

Cairngorm Parsley PureMVC Mate Swiz Robotlegs

10. Component lifecycle & the display list

I wasn't convinced of the need to learn the Flex component lifecycle or the display list until I wrote my first "custom" component (actually, it was a semi-custom component that extended Canvas). Until that time, I used built-in Flex components and blissfully lived in MXML land where the display list was handled for me. Never once did I encounter an addChild, createChildren or commitProperties method, and I used the creationComplete event for everything.

My first custom component utilized a handful of asynchronous events, and I could not reliably predict the order in which each event would be handled. Only after I learned of the Flex component lifecycle methods and dirty flags could I regain control.

These lifecycle methods are already there. Learn how they work and use them to your benefit. Your life will be easier and you'll lose less hair.

Colin Moock's Lost ActionScript Weekend - The Display List c Creating New Components in Flex 3 Diving Deep with the Flex Component Lifecycle Understanding the Flex 3 Component and Framework Lifecycle

Flex Basics - UI Controls

Posted by Jeremy Mitchell A Flex application's user-interface (UI) is composed of two component types — containers and controls. Containers define application layout and navigation; controls represent a broad category of UI objects required of a fully functional and interactive application.

Page 4: 10 Things a Good Flex Developer Should Know

Flex user interface controls are found in the mx.controls package of the Flex Class library.

Similar to the controls found on a traditional "Control Panel" (gauges, buttons, dials, indicators, etc), most Flex UI controls provide users control of your application.

However, despite the term, some Flex controls are not interactive and provide no control whatsoever. Examples of noninteractive controls include Label and ProgressBar.

The remainder are interactive controls and as such "can participate in tabbing and other kinds of keyboard focus manipulation, accept low-level events like keyboard and mouse input, and be disabled so that it does not receive keyboard and mouse input." Interactive controls provide the level of interaction required for users to perform desired tasks or business functions.

Common control types include text-based controls, button-based controls, and data provider controls (which include both list-based controls and menu-based controls).

Text-based controls are designed to display text and/or receive text input. Examples include Label, Text, TextArea, TextInput, and RichTextEditor.

Button-based controls receive user input in the form of keyboard or mouse events. Examples include Button, LinkButton, CheckBox, RadioButton and PopUpButton.

Data provider controls display data from a variety of sources, both internal and external to your application. All data provider controls require designation of a "data provider".

List-based controls (a subset of data provider controls) visually represent hierarchical or non-hierarchical (flat) data structures. Examples include ComboBox, List, HorizontalList, DataGrid, TileList and Tree.

Menu-based controls (another subset of data provider controls) enable user-initiated navigation through use of a static menu (always visible) or a popup menu (visibility is initiated by a user or system event). Examples include Menu, MenuBar and PopUpMenuButton.

All Flex controls subclass (or extend) the UIComponent class, and therefore, inherit the following key behaviors:

- resizing capabilities- positioning capabilities- ability to dispatch events - ability to accept keyboard focus and mouse input- ability to control visibility

Like all Flex UI components, controls can be sized, positioned and styled according to your needs.

Sizing requires the use of height and width properties - either explicitly (by setting the height and width properties to numeric pixel values) or relatively (using percentage values in relation to the parent container).

In many instances the positioning of a control is determined by the layout property (horizontal or vertical) of the parent container in conjunction with the hierarchical sequence of the control. For example, if a control represents the 3rd child element of a parent container with the layout property set to horizontal, the control will be positioned 3rd from the left.

Page 5: 10 Things a Good Flex Developer Should Know

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">

    <mx:Panel title="Panel Container with Horizontal Layout"        layout="horizontal"         paddingBottom="5" paddingLeft="5" paddingRight="5" paddingTop="5">               <mx:Button label="One"/>        <mx:Button label="Two"/>        <mx:Button label="Three"/>           </mx:Panel>   </mx:Application>

However, when the parent container uses absolute positioning, the X and Y properties of the control specify the horizontal and vertical pixel coordinates within the parent container. Absolute positioning enables overlap of controls if necessary.

Also, the appearance of a control can be customized through the use of styles and skins utilizing the CSS Explorer.

Fortunately, Flex ships with a number of pre-built controls ready for inclusion in your application. Most controls are accessible via MXML (or ActionScript) during the development phase of your Flex application. MXML provides a mechanism for creating (instantiating) control components (objects) and setting control properties (including registration of event handlers with control events).

At runtime, the same control properties (including event handlers) are accessible via ActionScript only. ActionScript also provides access to the methods (or functions) of a Flex control. Runtime access to Flex controls provides the dynamic capabilities required of highly interactive and responsive application.

Flex Basics - UI Containers

Posted by Jeremy Mitchell Flex containers serve as a mechanism for defining application layout and navigation. Common layout containers include VBox, HBox, Canvas, Tile and Form. Navigation containers include Accordion, Tab Navigator and View Stack. Each container descends from the Container Class, serves a unique purpose and is available for use at the discretion of the application developer.

Page 6: 10 Things a Good Flex Developer Should Know

Layout Containers

Layout containers dictate the layout of child elements (containers or controls) through the use of absolute or relative positioning. Absolute positioning requires definition of X and Y coordinates and permits overlap of elements. Relative positioning lays child elements next to each other either horizontally or vertically. Layout containers include:

- Application: default container provided at the root of your Flex application. There is no need to explicitly define the Application container as it comes part of any Flex application courtesy of the <mx:Application> tag. Organizes child containers vertically, horizontally or absolutely depending on the value of the layout attribute (horizontal, vertical or absolute)

- HBox: organizes child containers or controls horizontally

- VBox: organizes child containers or controls vertically

- HDividedBox: similar to an HBox with the distinction of a draggable divider in between each child container

- VDividedBox: similar to an VBox with the distinction of a draggable divider in between each child container

- Canvas: lays out child containers or controls based on absolute positioning (X and Y coordinates)

- Tile: lays out child containers or controls in columns or rows depending on the value of the direction attribute (horizontal or vertical)

- Panel: Similar to an HBox, VBox or Canvas container depending on the value of the layout attribute (horizontal, vertical or absolute) with the added benefit of a title bar

- Grid: similar to an HTML table it allows organization of child containers as rows and columns of cells

Control Containers

Control containers are used to manage the layout of controls (buttons, combo boxes, etc) only. Control containers include:

- ControlBar: only for use within a Panel or TitleWindow container, the ControlBar manages the layout of controls only (not child containers)

- ApplicationControlBar: one or more ApplicationControlBars may exist in a Flex application, however each must be a direct child of the Application container. Child components are limited to controls.

Navigation Containers

Navigation containers manage the navigation between containers by controlling the visibility of child containers. This visibility control can either be implemented by a nav bar (LinkBar, TabBar, ToggleButtonBar, etc) or by custom event handlers. Navigation containers include:

- Accordion: contains a collection of child containers and manages the visibility of each through the use of

Page 7: 10 Things a Good Flex Developer Should Know

accordion headers (similar to nav buttons)

- View Stack: contains a collection of child containers stacked on top of each other. A View Stack is not tied to a particular component responsible for managing visibility but many options exist (i.e LinkBar, TabBar, ToggleButtonBar) for the developer's use

- Tab Navigator: identical to a View Stack except for a built-in navigation feature, TabBar

Containers may serve as a parent container, a child container or both a parent and child container in relation to another container.

The following example demonstrates the simultaneous use of a Canvas container as both a a parent container and a child container.

<mx:VBox width="100%" height="54">   <mx:Image source="assets/logo.png" />   <mx:Canvas height="30">      <mx:Label x="9" y="7" text="Manage Athletes" />      <mx:Label y="6" text="[ Log Out ]" right="5" />   </mx:Canvas></mx:VBox> In most cases, a layout container is not limited to a certain context. Exceptions include the Application container, the ApplicationControlBar container and the ControlBar container.

- Application container: as the root of the Flex application, only one instance of the Application container may exist and can ONLY be a parent container.

- ApplicationControlBar container: as the name suggests, the ApplicationControlBar container defines an area intended to house a control bar for your Flex application. As such, this container can only be defined as a direct child to the Application container.

- ControlBar container: intended to dock a toolbar to a Panel or TitleWindow container, a ControlBar container must be defined as a direct child to a Panel or TitleWindow container

All other containers are available for use in any context. For example, a Canvas container may be defined as a child to a parent VBox, HBox, Tile or even another Canvas container.

Given the hierarchical (parent/child) nature of application layout (containers), best practices suggest the use of MXML (an XML derivative) instead of ActionScript.

Toggling between Design mode and Source mode of Flex Builder, the hierarchical nature of your Flex application will be clear. In Design mode, your Flex application is arranged as nested containers and controls. This arrangement represents a hierarchy (or parent / child structure) and can be verified using the Outline View (Window >> Show View >> Outline). In Source mode, your Flex application is represented in MXML which by nature is hierarchical.

When your Flex application is ultimately translated into ActionScript, another type of hierarchy will emerge - an Object hierarchy. Afterall, a Flex application is nothing more than one Application object composed of other objects composed of other objects...and so on...and MXML is a mapping of your Flex application's object hierarchy to XML.

Page 8: 10 Things a Good Flex Developer Should Know

Flex Basics - Data Binding

Posted by Jeremy Mitchell There are many reasons to choose Flex as your development platform for web-based software applications. Everyone is already familiar with Adobe's claim of a superior user experience delivered via Flex's rich client (aka fat or thick client). However, developers and project sponsors alike are drawn to features of the Flex SDK which promote rapid development of feature-rich, robust applications.

Data binding is a great example of one of these features.

Exposed through the MXML API, data bindings allow developers to "bind" the value of one object property (destination property) to the value of another object property (source property) using MXML or MXML + inline ActionScript.

<mx:Binding source="source.text" destination="destination.text" />

<mx:TextInput id="source" /><mx:TextInput id="destination" />

OR 

<mx:TextInput id="source" /><mx:TextInput id="destination" text="{source.text}" /> By utilizing data bindings, any change to the value of the source property is immediately reflected in the destination property. It is important to note that data bindings are "one way". Source property changes affect the destination property value but not vice versa.

One benefit of using the <mx:Binding> tag instead of inline ActionScript is the ability to bind a property to multiple source properties. If any of the source properties change so does the destination property.

<mx:Binding source="source.text" destination="destination.text"/><mx:Binding source="source2.text" destination="destination.text"/>

<mx:TextInput id="source"/><mx:TextInput id="source2"/>

<mx:TextInput id="destination"/> However, both methods allow you to perform operations on a source property value or derive a value from the combination of multiple source properties. See Binding Expressions discussed later.

Note: a source property can only be identified for data binding if the object to which it belongs has an id property.

Although it is possible to bind the text property of one TextInput control to the text property of another TextInput control as demonstrated in the previous example, data binding is not limited to such a scenario.

Properties of visual elements may be bound to non-visual elements and vice versa. In fact, an predominant Flex architecture, MVC, relies on the ability to bind visual elements in the "view" to non-visual elements in the "model".

Also, you could bind the text property of a TextInput control to the selectedIndex property of a ComboBox

Page 9: 10 Things a Good Flex Developer Should Know

control if you so choose.

Data bindings are not limited to the binding of "like" properties or "like" elements.

Note that data bindings are, however, limited to properties of identical data types or scenarios where type casting is possible. For example, you can bind a property with a data type String (i.e. text property) to a property with a data type of Int (i.e. selectedIndex) since an Int can be implicitly cast to a String. However, the reverse is not true - a property with a data type of Int cannot be bound to a property with a data type of String.

Data binding could also be accomplished by using ActionScript to add an event listener to the source object which listens for a specified event and calls a specified event handler method responsible for changing the destination object's property value to the source object's property value.

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="init()">

<mx:Script>  <![CDATA[    private function init():void {      source.addEventListener(KeyboardEvent.KEY_UP,updateValue);    }      private function updateValue(event:KeyboardEvent):void {      destination.text = source.text;    }  ]]></mx:Script>

<mx:TextInput id="source" /><mx:TextInput id="destination" />

MXML data binding just allows you to do it easier and with less code.

While some may refer to such capabilities as nothing more than "syntactic sugar", most developers can appreciate the convenience and accessibility demonstrated by Flex's MXML implementation of data bindings.

Keep in mind that using MXML to bind data binds the properties to one another at compile time. If you want to bind data at runtime based on a condition, you will have to use ActionScript.

Binding Expressions

A data binding is the simplest form of a binding expression.

More advanced binding expressions combine the use of data bindings with ActionScript operations. Since binding expressions define the value of an MXML attribute, they must return a value and be wrapped in curly braces. Without curly braces, your binding expression will be interpreted as a literal value.

Binding expression are most commonly used to accomplish the following:1. Bind the value of one object property to the property of another object (simple data binding)2. String concatenation that includes one or more binded properties 3. Calculations on one or more binded properties 4. Conditional operations on one or more binded properties

Page 10: 10 Things a Good Flex Developer Should Know

Simple data binding:

<mx:ComboBox id="c" dataProvider="{myArray}" />

<mx:ViewStack id="v" selectedIndex="{c.selectedIndex}">  <mx:Canvas>    <mx:Label text="1"/>  </mx:Canvas>  <mx:Canvas>    <mx:Label text="2"/>  </mx:Canvas></mx:ViewStack>

OR 

<mx:ComboBox id="c" dataProvider="{myArray}" />

<mx:Binding source="c.selectedIndex" destination="v2.selectedIndex" />

<mx:ViewStack id="v2">  <mx:Canvas>    <mx:Label text="1"/>  </mx:Canvas>  <mx:Canvas>    <mx:Label text="2"/>  </mx:Canvas></mx:ViewStack> String concatenation:

<mx:TextInput id="fname" /><mx:TextInput id="lname" />

<mx:Label text="{'First Name: ' + fname.text}" /><mx:Label text="{'Full Name: ' + fname.text + ' ' + lname.text}" />

OR

<mx:TextInput id="fname" />

<mx:Binding source="{'First Name: ' + fname.text}" destination="destination.text" />

<mx:Label id="destination"/> Calculations:

<mx:NumericStepper id="quantity" />

<mx:TextInput id="price" />

<mx:Label text="{'Total: ' + quantity.value * Number(price.text)}" />

Page 11: 10 Things a Good Flex Developer Should Know

OR 

<mx:NumericStepper id="quantity" />

<mx:TextInput id="price" />

<mx:Binding source="{'Total: ' + quantity.value * Number(price.text)}" destination="destination.text" />

<mx:Label id="destination"/> Conditional:

<mx:NumericStepper id="quantity" />

<mx:Label text="{(quantity.value % 2) ? 'Odd' : 'Even'}" />

OR 

<mx:NumericStepper id="quantity" />

<mx:Binding source="{(quantity.value % 2) ? 'Odd' : 'Even'}" destination="destination.text" />

<mx:Label id="destination"/>

Flex Tips - Using Bindable Metadata Events

Posted by Jeremy Mitchell One powerful feature of Flex is data binding. On the surface, data binding is simple to implement.

1. Mark a class as bindable to activate data binding on all public properties of the class

[Bindable]public class Order Or, mark individual properties as bindable

public class Order{    public function Order()    {    }       [Bindable]    public var orderNumber:int;       [Bindable]    public var orderName:String;} 2. Declare an instance of the class preceded with the [Bindable] metadata tag

[Bindable]private var order:Order = new Order();

Page 12: 10 Things a Good Flex Developer Should Know

3. Use a bindable property as the source of a data binding association. 3 techniques exist:

Wrap the source property in curly brackets

<mx:Label id="myLabel" text="{order.orderName}"/> Use a Binding tag

<mx:Binding source="order.orderName" destination="myLabel.text"/> Create the data binding association at runtime

BindingUtils.bindProperty(myLabel, "text", order, "orderName"); The most common practice includes the use of curly brackets. The following example demonstrates data binding in its simplest form.

// Value object class marked bindable    [Bindable]public class Order{    public function Order()    {    }       public var orderNumber:int;    public var orderName:String;}

<!-- Application file --><mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"         layout="vertical">        <mx:Script>        <![CDATA[            import comps.Order;                        [Bindable]            private var order:Order = new Order();        ]]>    </mx:Script>        <!-- binding #1 -->    <mx:Label  text="{'Order #: ' + order.orderNumber}"/>         <!-- binding #2 -->    <mx:Text text="{'Order Name: ' + order.orderName}"/>        <mx:HBox>            <mx:Button label="Change Order #" click="order.orderNumber = Math.floor(Math.random()*50)+1"/>        <mx:TextInput id="ti" text="Enter name..." enter="order.orderName = ti.text" />        

Page 13: 10 Things a Good Flex Developer Should Know

    </mx:HBox>    </mx:Application> In most scenarios, this approach is acceptable. However, there are times when another technique is recommended. It involves explicitly defining which event type to dispatch when a source property changes. Let's review what we did previously.

We marked an entire class as bindable

[Bindable]public class Order Or, marked individual properties as bindable

public class Order{    public function Order()    {    }       [Bindable]    public var orderNumber:int;       [Bindable]    public var orderName:String;} This is equivalent to:

[Bindable(event="propertyChange")]public class Order Or

public class Order{    public function Order()    {    }       [Bindable(event="propertyChange")]    public var orderNumber:int;       [Bindable(event="propertyChange")]    public var orderName:String;} Data binding includes a lot of code generation. This is part of it. When using the [Bindable] metadata tag without explicitly defining the event type, the default event type is used – propertyChange.

Using the default event type (propertyChange) is fine except when you mark the entire class as bindable and the class contains several public properties (see Cairngorm's ModelLocator class). In this case, each public property will dispatch the same event type (propertyChange) when their value changes. This can be problematic.

Page 14: 10 Things a Good Flex Developer Should Know

To understand why this is a problem, let's take a closer look at what happens behind the scenes when data binding is used.

Note: This is a very high-level analysis of the inner-workings of data binding. For a detailed description of data binding, check out Michael Labriola's presentation entitled Diving in the Data Binding WatersTo accomplish data binding, here's what is required of you:

First, mark a class as bindable to activate data binding on all public properties of the class:

[Bindable]public class Order Or, mark individual properties as bindable

public class Order{    public function Order()    {    }       [Bindable]    public var orderNumber:int;       [Bindable]    public var orderName:String;} By doing this, the Flex framework does the following by generating more code:

Turns your class into an "event dispatcher" by implementing IEventDispatcher Implements the methods required of the IEventDispatcher interface (addEventListener,

removeEventListener, dispatchEvent, etc) Creates implicit getters and setters for each bindable property Converts [Bindable] to [Bindable(event="propertyChange")] Adds code to your setter method required to dispatch the propertyChange event when the property value

changes.

Why does the Flex framework do all of this? In a nutshell, so your class can:1. Broadcast an event when a bindable property value changes2. Allow interested parties to register an event listener triggered when a bindable property changes

But wait, there's more! When you actually use a bindable property as the source of a data binding (via curly brackets, Binding object or BindingUtils.bindProperty), the Flex Framework generates even more code required to:

1. Create an array of Binding objects

One Binding object is created for each data binding association. Each Binding object is responsible for updating a destination property when the corresponding source property changes.

2. Create an array of PropertyWatcher objects

One PropertyWatcher object is created for each data binding association. Each PropertyWatcher object is responsible for "listening" for an event to occur that signifies a change in the source property value.

Page 15: 10 Things a Good Flex Developer Should Know

The event type is determined by the value defined in the [Bindable] metadata tag. Again, if no type is defined, propertyChange is used.

Failure to specify an event type in the [Bindable] metadata tag forces every public property to dispatch a propertyChange event when their value changes, and, in turn, every PropertyWatcher is "listening" for a propertyChange event. However, only the PropertyWatcher tasked with watching the property that actually changed is required to respond to the event and notify the Binding object responsible for updating the destination property.

The extra work involved with triggering multiple PropertyWatcher objects when only ONE source property changes can be expensive and can be avoided by simply defining a unique event for each bindable property. The following example demonstrates this technique.

// Value object that dispatches unique events for each bindable property

package comps{    import flash.events.Event;    import flash.events.EventDispatcher;        public class Order extends EventDispatcher    {        public function Order()        {        }               private var _orderNumber:int;               [Bindable(event="orderNumberChange")]        public function get orderNumber():int {            return _orderNumber;        }               public function set orderNumber(value:int):void {            if ( _orderNumber !== value ) {                _orderNumber = value;                // remember to dispatch the unique event                dispatchEvent(new Event("orderNumberChange"))            }        }               private var _orderName:String;                [Bindable(event="orderNameChange")]        public function get orderName():String {            return _orderName;        }               public function set orderName(value:String):void {            if ( _orderName !== value ) {                _orderName = value;

Page 16: 10 Things a Good Flex Developer Should Know

                // remember to dispatch the unique event                dispatchEvent(new Event("orderNameChange"))            }        }

    }}

<?xml version="1.0" encoding="utf-8"?><mx:Application    xmlns:mx="http://www.adobe.com/2006/mxml"    layout="vertical">       <mx:Script>        <![CDATA[            import comps.Order;                       [Bindable]            private var order:Order = new Order();        ]]>    </mx:Script>       <!-- binding #1 -->    <mx:Label id="myLabel" text="{'Order #: ' + order.orderNumber}"/>       <!-- binding #2 -->    <mx:Text text="{'Order Name: ' + order.orderName}"/>       <mx:HBox>           <mx:Button label="Change Order #" click="order.orderNumber = Math.floor(Math.random()*50)+1"/>        <mx:TextInput id="ti" text="Enter name..." enter="order.orderName = ti.text" />           </mx:HBox>   </mx:Application>

Flex Basics - Item Renderer

Posted by Jeremy Mitchell One characteristic of a well-designed Flex application is the ability to present data in a visually-compelling manner. Outside of the database and within the model layer of a Flex application, data is stored in a flat or hierarchical fashion (i.e. ArrayCollection or XMLListCollection). Although a great format for data storage or transport, flat or hierarchical data structures lack significant meaning to the average user.

Fortunately, Flex provides a handful of UI controls designed to render flat or hierarchical data in an intuitive, meaningful and compelling manner within the UI. These UI controls include those that extend the ListBase class and are commonly referred to as list-based controls. Since a collection of data can also be referred to as a list, the name makes sense.

Page 17: 10 Things a Good Flex Developer Should Know

List-based controls include DataGrid, List, Tree, Menu, TileList and HorizontalList. Each list-based control contains a public dataprovider property. The value of the dataprovider property represents the data collection (or list) that requires the list-based control to render its contents in the UI.

Just as a list has items, so does a data collection. An item is analogous with a row or a record in a flat data set or a node within a hierarchical data set (i.e. XML). Data collections contain one or more items. In turn, each item may contain one or more properties.

The following example illustrates storage of flat data:

Note:By default, list-based controls render the contents (properties) of each item (row or record) as simple text. In many scenarios, a textual rendering is sufficient. In others it is not.

Let's examine a scenario where you've selected a DataGrid control to render data stored in an ArrayCollection. In this scenario, your ArrayCollection houses a "list" of 10 employees. Each employee "record" has 4 properties - firstName, lastName, age, photo. Each employee property with the exception of the photo property fits nicely with the DataGrid's default textual rendering.

To customize the rendering format of an item property (i.e. employee photo), utilize the itemrenderer property. Item Renderers control the display of data for each item property. If you do not specify an Item Renderer, the default is used and the item property is displayed as simple text.

Since simple text is not an acceptable display for the employee photo property in our previous example, a custom Item Renderer is required.

3 types of custom Item Renderers exist:

1. Drop-In Item Renderers 2. Inline Item Renderers3. External Item Renderers

Each type requires access to the data in which it will render and, therefore, any component acting as an Item Renderer must implement the IDataRenderer interface. The IDataRender interface enforces the implementation of a public getter and setter method for the data property. Without these methods, the list-based control that contains the data (host component) cannot pass item data to the component acting as an Item Renderer.

Fortunately, all Flex containers and many Flex controls implement the IDataRenderer interface and contain the required data property. To be sure, you may want to check the inheritance tree of the component you are considering as an Item Renderer. The inheritance tree can be found for each Flex component at the Flex 3 Language Reference.

Drop-In Item Renderers

Page 18: 10 Things a Good Flex Developer Should Know

Several UI controls within the Flex SDK were designed to serve as Drop-In Item Renderers - Button, CheckBox, DateField, Image, Label, NumericStepper, Text, TextArea, and TextInput. These controls all implement the IDropInListItemRenderer interface.

Drop-In Item Renderers are generic in nature and don't rely on specific data fields to render data. This allows them to be used with a wide range of data sets, hence, the term “drop-in”. Drop-In Item Renderers can be “dropped-in” to any list-based control regardless of the dataprovider’s data properties.

In our previous example, the employee photo property requires use of a custom Item Renderer to render properly in the UI. In this scenario the Image component satisfies our rendering needs out of the box. Implemented as a Drop-In Item Renderer, the Image component takes any data property regardless of name and uses it as the Image component's source property value. Assuming our employee photo property contains a valid image path, the Image Drop-In Item Renderer will work perfectly and resolve the image path as an image in the UI.

<!-- Drop-in Item Renderer: Image control --><mx:DataGridColumn dataField="photo"                    headerText="Employee Photo"                    itemRenderer="mx.controls.Image"/> Drop-In Item Renderers are simple and easy to use and satisfy specific use cases nicely. However, they provide no flexibility whatsoever. If your needs are not satisfied by a Drop-In Item Renderer, you must create your own Item Renderer as an inline component or an external component.

Inline Item RenderersGenerally used for simple item rendering requiring minimal customization, inline Item Renderers are defined as a component nested within the MXML of your list-based control.

It is important to note that Item Renderers nested within the itemrender property of a list-based control occupy a different scope than the list-based control. Any attempt to reference members (properties or methods) of the parent component from the nested Item Renderer component will result in a compile-time error. However, references to the members of the parent component can be achieved by utilizing the outerDocument object.

<mx:DataGrid id="myGrid" dataProvider="{gridData}">   <mx:columns>      <mx:DataGridColumn headerText="Show Relevance">         <mx:itemRenderer>            <mx:Component>               <mx:Image source="{'assets/images/indicator_' + data.showRelevance + '.png'}"                          toolTip="{(data.showRelevance == 1) ? 'On' : 'Off'}"                         click="outerDocument.toggle()" />            </mx:Component>         </mx:itemRenderer>      </mx:DataGridColumn>   </mx:columns></mx:DataGrid>

Remember, rules of encapsulation still apply. Mark all properties or methods public if you want them accessible by your inline Item Renderer. In the previous example, the toggle() method must have a public access modifier to expose itself to the inline Item Renderer.

public function toggle():voi

Page 19: 10 Things a Good Flex Developer Should Know

d

Inline Item Renderers can also be reusable by creating a named component instance outside of the list-based control. This component must have an id property and contain the rendering logic of the Item Renderer. Using data bindings, the component is assigned to the itemrenderer property of one or more data properties of a list-based control.

<!-- Reusable inline Item Renderer --><mx:Component id="ImageRenderer">   <mx:VBox width="100%" height="140"            horizontalAlign="center" verticalAlign="middle">      <mx:Image source="{'assets/'+data.image}"/>      <mx:Label text="{data.image}" />   </mx:VBox></mx:Component>

<!-- Used within a list-based control--><mx:DataGridColumn headerText="Image"                   dataField="image" width="150"                   itemRenderer="{ImageRenderer}"/> In the previous example, note that the Item Renderer component contains 2 UI controls – Image and Label. When using multiple controls within an Item Renderer, a layout container is required. In this example, a VBox was used.

External Item Renderers

As the complexity of your Item Renderer increases, you may want to create a custom MXML component or ActionScript class to encapsulate the Item Renderer.

Once built, the Item Renderer component is assigned to the itemrenderer property of the appropriate list-based control property. Note that the path to the Item Renderer component is not relative to the current file but rather is relevant to the MXML file containing your Application tags.

<!-- Custom Component: ImageRender.mxml --><mx:VBox width="100%" height="140"         horizontalAlign="center" verticalAlign="middle">   <mx:Image source="{'assets/'+data.image}"/>   <mx:Label text="{data.image}" /></mx:VBox>

<!-- Used within a list-based control--><mx:DataGridColumn headerText="Image"                   dataField="image" width="150"                   itemRenderer="components.ImageRenderer"/> There is very little difference between an external Item Renderer and an inline Item Renderer. However, external Item Renderers are ideal for modularity, reuse and maintainability.

To continue the discussion of Item Renderers and take a much closer look, read Peter Ent's 5 part article entitled Understanding Flex itemRenderers or see an example of an Item Renderer in practice.

Flex Examples - Item Renderers in Practice

Page 20: 10 Things a Good Flex Developer Should Know

List-based controls (DataGrid, List, TileList & HorizontalList) render the data assigned to their dataProvider property.

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"    layout="vertical">

    <mx:ArrayCollection id="ac">        <mx:Array>            <mx:Object name="tom" age="12" hair="brown"/>            <mx:Object name="sally" age="21" hair="green"/>            <mx:Object name="kate" age="16" hair="yellow"/>            <mx:Object name="bill" age="22" hair="brown"/>            <mx:Object name="chriss" age="23" hair="green"/>            <mx:Object name="yarb" age="34" hair="yellow"/>        </mx:Array>    </mx:ArrayCollection>        <mx:List id="myList"        dataProvider="{ac}"        labelField="name"/>

</mx:Application>

With the help of an Item Renderer, list-based controls can customize the appearance of the data provider's data.

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"    layout="vertical">        <mx:ArrayCollection id="ac">        <mx:Array>            <mx:Object name="tom" age="12" hair="brown"/>            <mx:Object name="sally" age="21" hair="green"/>            <mx:Object name="kate" age="16" hair="yellow"/>            <mx:Object name="bill" age="22" hair="brown"/>            <mx:Object name="chriss" age="23" hair="green"/>            <mx:Object name="yarb" age="34" hair="yellow"/>        </mx:Array>    </mx:ArrayCollection>        <!-- Using an Item Renderer to control the display of data -->    <mx:List width="100%"        dataProvider="{ac}"        itemRenderer="com.flexdevelopers.ListIR"/>

</mx:Application>

<!-- Item Renderer (ListIR.mxml) -->

<mx:Label xmlns:mx="http://www.adobe.com/2006/mxml"    text="{data.name + ' (' + data.age + ')'}"

Page 21: 10 Things a Good Flex Developer Should Know

    color="0xFF0000"/> In addition, the custom appearance can be controlled by conditional logic processed by an Item Renderer. We'll look at this a bit later.

A single instance of your Item Renderer class (ListIR) is created for each visible item of the list-based control.

”As the user scrolls through the items of a list-based control, Item Renderer instances are recycled rather than creating new instances.”

Example: When Data Item #1 is removed from the list-based control's display due to a scrolling action, the Item Renderer instance previously used to render Data Item #1 is recycled and used to display the data for Data Item #6.

Item Renderers must directly or indirectly (through class inheritance) implement the IDataRenderer interface which enforces the implementation of 2 very important methods: getdata() & setdata(). With an implicit getter and setter in place for the data property, the Item Renderer instance can receive a data object passed from the host component (the list-based control) which represents the data for the item it is responsible to render (i.e. Data Item #6).

Example: If instance #1 of the Item Renderer is rendering the data for Data Item #6, the data for Data Item #6 is passed to instance #1 of the Item Renderer via the Item Renderer's set data setter method.When an instance of an Item Renderer is recycled due to scrolling, the set data method is called and the applicable data object is passed. This is the point in which conditional logic can be applied to control the appearance of an Item Renderer.

<!-- Item Renderer (ListIR.mxml) with conditional logic -->

<mx:HBox xmlns:mx="http://www.adobe.com/2006/mxml">    <mx:Script>        <![CDATA[            private var minAge:Number = 21;                                    override public function set data(value:Object):void {

Page 22: 10 Things a Good Flex Developer Should Know

                super.data = value; // set the Item Renderer's data object                // inject additional logic                if (data.age < minAge) {                    listLabel.setStyle("color",0xFF0000);                } else {                    listLabel.setStyle("color",0x000000); // default value                }            }        ]]>    </mx:Script>    <mx:Label id="listLabel"        text="{data.name + ' (' + data.age + ')'}"/></mx:HBox> Note: It is important to remember that Item Renderers are recycled and as such, their property values may reflect a condition met by the previous "user" of the Item Renderer instance (i.e. the Data Item). Therefore, it is important to reset properties to the default value when conditional logic fails. In the previous example, the reset is accomplished by setting the label's font color back to black (0x000000) when data.age >= 21.In the previous example, we utilized a property of the data object (data.age) and a hard-coded value (21) to dictate the item's appearance. However, certain scenarios may require access to property values outside of an Item Renderer's scope to determine the appearance.

Example: The value of an HSlider in conjunction with the age property of the data object (data.age) should dictate the font color of each item's label.This scenario requires the following:

1. Create a new public property for the list-based control exposed via a getter and setter

By extending an existing class and adding a new public property, our list-based control will have a place to store the value of an external property (i.e. the value of the HSlider's value property).

// MyList.as extends List

package com.flexdevelopers{    import mx.controls.List;

    public class MyList extends List    {        private var _minAge:Number; // new property                public function MyList()        {            super();        }

        // new property getter and setter methods               public function get minAge():Number {            return _minAge;        }        

Page 23: 10 Things a Good Flex Developer Should Know

        public function set minAge(value:Number):void {            _minAge = value;        }            }}

2. Bind the new list-based control's public property (MyList.minAge) to the value of the desired external property utilizing Flex's data-binding utility

Data-binding will provide real-time synchronization of the new public property (minAge) with the external property's value (i.e. the HSlider's value property)

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:comps="com.flexdevelopers.*"    layout="vertical">        <mx:Script>        <![CDATA[            import com.flexdevelopers.MyList;        ]]>    </mx:Script>

    <mx:ArrayCollection id="ac">        <mx:Array>            <mx:Object name="tom" age="12" hair="brown"/>            <mx:Object name="sally" age="21" hair="green"/>            <mx:Object name="kate" age="16" hair="yellow"/>            <mx:Object name="bill" age="22" hair="brown"/>            <mx:Object name="chriss" age="23" hair="green"/>            <mx:Object name="yarb" age="34" hair="yellow"/>        </mx:Array>    </mx:ArrayCollection>        <comps:MyList width="100%"        dataProvider="{ac}"        itemRenderer="com.flexdevelopers.ListIR"        minAge="{hslider.value}"/> <!-- minAge is bound to hslider.value -->        <mx:HBox>

        <mx:HSlider id="hslider"            minimum="10" maximum="50"            value="20"            snapInterval="1"            liveDragging="true"/>                    <mx:Label text="Minimum Drinking Age: {hslider.value}"/>            </mx:HBox>

Page 24: 10 Things a Good Flex Developer Should Know

</mx:Application>

3. Provide the Item Renderer with access to a ListData object

To access the value of our new public property from within an Item Renderer instance, our Item Renderer must implement the IDropInListItemRenderer interface. This ensures a reference to the Item Renderer's owner (the list-based control) is available to the Item Renderer, and consequently, so is our new public property.

<!-- ListIR.mxml -->

<mx:HBox xmlns:mx="http://www.adobe.com/2006/mxml"       implements="mx.controls.listClasses.IDropInListItemRenderer">    <mx:Script>        <![CDATA[            import mx.controls.listClasses.BaseListData;            import mx.controls.listClasses.ListData;            import com.flexdevelopers.MyList;                        // property required of IDropInListItemRenderer exposed thru a public getter & setter            private var _listData:BaseListData;                        // getter & setter methods            public function get listData():BaseListData {                return _listData;            }                        public function set listData(value:BaseListData):void {                _listData = value;            }                        override public function set data(value:Object):void {                super.data = value;                // retrieve the value of the list-based control's new public property                var minAge:Number = (listData.owner as MyList).minAge;                if (data.age < minAge) {                    listLabel.setStyle("color",0xFF0000);                } else {                    listLabel.setStyle("color",0x000000);                }            }        ]]>    </mx:Script>        <mx:Label id="listLabel"        text="{data.name + ' (' + data.age + ')'}"/>    </mx:HBox>

4. Make a call to the invalidateList method when the source of our new, bounded public property is changed (i.e. the HSlider value property changes)

Page 25: 10 Things a Good Flex Developer Should Know

By calling MyList.invalidateList() each time the HSlider value changes, we ensure that the conditional logic of the Item Renderer is re-evaluated. InvalidateList forces each Item Renderer instance of a list-based control to call the data setter method.

// update the new property's setter method to include invalidateList()// IMPORTANT: Without calling invalidateList, a change to the HSlider will not impact 

// the appearance of the currently visible list items

public function set minAge(value:Number):void {   _minAge = value;   invalidateList();}

Flex Basics - ArrayCollection

Posted by Jeremy Mitchell Arguably one of the most useful constructs available to a Flex developer is an Array. Designed to store data of various types accessible via a numbered index, the Array class provides a useful mechanism for data storage and retrieval.

As such, an Array would appear to satisfy the data provider needs of any list-based control. However, it does not. Incompatibility with data binding makes an Array a poor choice of data provider. Fortunately, Flex provides a suitable alternative - ArrayCollection. An ArrayCollection provides all the features of an Array plus more.

To understand an ArrayCollection, one must first understand an Array.

Array

From Wikipedia, an Array "is a data structure consisting of a group of elements that are accessed via indexing". Arrays can store simple data types (primitives) such as number, boolean or string or complex data types such as other Arrays or objects.

In fact, Arrays defined in ActionScript (or MXML) are not strongly-typed and can store various types of data.

private var myArray:Array = new Array();myArray[0] = "Tom"; // stringmyArray[1] = 2; // numbermyArray[2] = new Object(); // object Array elements can be retrieved or set using array access notation utilizing the zero-based index value of the desired element.

// retrieving the value of an array elementprivate var name:String = myArray[0];

// setting the value of an array elementmyArray[0] = "Bill";

Page 26: 10 Things a Good Flex Developer Should Know

Note: Arrays are designed to use a numbered index. If you intend to retrieve data via a named index (i.e. Associative Array or HashMap), you may want to consider using an object as a data container. Unlike other classes, the Object class is dynamic - meaning arbitrary properties can be added to serve as keys.

var myObject:Object= new Object();myObject.name = "Tom";myObject.age = 27; If your HashMap keys include spaces, use array access notation.

var myObject:Object= new Object();myObject["first name"]= "Tom"; HashMap values can be retrieved or set using dot notation (if no spaces in the key) or array access notation.

// retrieving the value of an object via an named index using dot notationprivate var name:String = myObject.name;

// setting the value of an object property using dot notationmyObject.name = "Bill";

// retrieving the value of an object via an named index using array access notationprivate var firstName:String = myObject["first name"];

// setting the value of an object property using array access notationmyObject["first name"] = "Bill"; Arrays are dynamic and, therefore, can be resized simply by adding or removing elements.

// adds an element to the end of an array and increases the array length by onemyArray.push("Phil");

// removes the last element from an array and decreases the array length by onemyArray.pop(); ActionScript supports two methods for creating Arrays, each with a variety of syntaxes:

Method #1 – Create an Array by defining (or not defining) the number of elements

// creates an array with zero elements (this is the default when no argument is passed to the Array constructor)private var myArray:Array = new Array();

// creates an array with 10 elementsprivate var myArray:Array = new Array(10);

// creates an array with zero elements using literal notationprivate var myArray:Array = []; Method #2 – Create an array by defining the array elements and their values

private var myArray:Array = new Array("red",2);private var myArray:Array = ["red",2]; Note: The Array class can support both initialization techniques by providing two class constructors. The appropriate constructor is used based on the argument value(s) (or lack thereof).

Page 27: 10 Things a Good Flex Developer Should Know

Arrays can also be built using MXML:

<mx:Array id="myArray"/> <!--creates an array with zero elements-->

<mx:Array id="myArray"> <!--creates an array with three elements-->   <mx:String>myString</mx:String> <!--string-->   <mx:Number>98</mx:Number> <!--floating-point number-->   <mx:Object name="Phil" age="27"/> <!--object--></mx:Array> Like everything in Flex, an Array is an object and as such it contains a handful of useful properties and methods.

One property familiar to all developers is the length property. The length property represents the number of array elements.

private var myArray:Array = new Array(10);private var numberOfArrayElements:uint = myArray.length; // 10 Note: Although each Array element contains an undefined value in this scenario, the length is still 10.

The length property can be very handy. One popular technique involves using the length property to dictate the number of loops included in a For Loop.

for (var i:uint; i < myArray.length; i++) {   trace(myArray[i]);} Note: You can truncate an Array by setting the length property to a value less than the number of array elements. This is not true of an ArrayCollection as the length property is read-only.

By utilizing the methods of the Array class, you can perform a number of operations on the Array elements or the Array itself. Popular Array methods include:

* filter* indexOf* join* push* reverse* slice* sort* toString

However, despite all of an Array's powerful features, the inability to support data binding is a significant shortcoming. Fortunately, Flex provides an ArrayCollection.

ArrayCollection

Per the Flex Language Reference, an ArrayCollection is a "wrapper class that exposes an Array as a collection that can be accessed and manipulated using the methods and properties of the ICollectionView or IList

Page 28: 10 Things a Good Flex Developer Should Know

interfaces".

Two members of the ArrayCollection class are integral to the ArrayCollection's ability to support data binding - The collectionChange event and addEventListener method. To participate in data binding, an object must be able to:

1. dispatch an event when something changes2. allow other objects to listen and respond to events

The ArrayCollection satisfies both thanks to the collectionChange event and the addEventListener method and will support data binding when given a compiler directive to do so using the [Bindable] metadata tag.

// creates a bindable ArrayCollection with zero elements[Bindable] private var myArrayCollection:ArrayCollection = new ArrayCollection(); An ArrayCollection can be created in one of three ways:

// creating ArrayCollection with zero elementsprivate var myArrayCollection:ArrayCollection = new ArrayCollection();

// passing an existing Array into an ArrayCollection via the constructorprivate var myArrayCollection:ArrayCollection = new ArrayCollection(myArray);

// assigning an existing Array to the source property of an ArrayCollectionprivate var myArrayCollection:ArrayCollection = new ArrayCollection();myArrayCollection.source = myArray; Either method successfully wraps an Array inside an ArrayCollection and as such, extends the capabilities of an Array.

Note: In Flex, ActionScript classes can have optional constructor parameters only. MXML does not enforce required constructor parameters, therefore, if a constructor parameter is required to create a new instance of a class, provide a default value. In the case of an ArrayCollection, the default argument for the source parameter is NULL, hence, an empty ArrayCollection is created when the source parameter is omitted.

Extending the ListCollectionView class that implements the ICollectionView and IList interfaces, an ArrayCollection inherits a handful of properties, methods and events. Therefore, your plain old Array now has a new set of functionality.

New properties include (but not limited to):

* filterFunction* length* list* sort* source

New methods include (but not limited to):

* addEventListener* addItem* addItemAt* contains

Page 29: 10 Things a Good Flex Developer Should Know

* getItemAt* getItemIndex* refresh* removeAll* removeItemAt* setItemAt

Once an Array is wrapped inside an ArrayCollection, the properties and methods of the Array class are no longer accessible unless you access them through the Array object directly. For example, if you really want to use the Array's push method, you could do the following:

myArrayCollection.source.push("new element"); This would require using the ArrayCollection's refresh method to trigger data binding.

myArrayCollection.source.push("new element");myArrayCollection.refresh(); However, you could always use the ArrayCollection's addItem method instead.

myArrayCollection.addItem("new element"); Realize that every ArrayCollection contains an Array as the data source. If you create an empty ArrayCollection and add elements using the methods of the ArrayCollection rather than assigning an Array to the source property of an ArrayCollection, an Array is created for you.

Any data manipulation performed on an ArrayCollection will be reflected in the underlying Array and vice-versa, however, it is important to note that manipulating an Array directly will not be reflected inside an ArrayCollection until you perform a refresh of the ArrayCollection using the ArrayCollection's refresh method.

Using an ArrayCollection in place of or in tandem with an existing Array provides Flex developers with a valuable and responsive data storage and retrieval mechanism.

Flex Basics - XMLListCollection

Posted by Jeremy Mitchell Depending on the characteristics of a data set, data can be modeled in a linear or hierarchical fashion.

Linear data (aka flat or list-based data) typically represents the attributes (or properties) of an individual entity (item).

In turn, multiple items can be aggregated into a list and stored in an Array. An Array provides a mechanism for storage, manipulation and retrieval of linear data within a Flex application.

Page 30: 10 Things a Good Flex Developer Should Know

Note: Arrays can also store hierarchical data (i.e. objects composed of other objects or simple xml objects) but you'll find linear data to be more common.Other data sets represent nested levels of information (hierarchical data). ActionScript provides two native datatypes for working with hierarchical data – XML and XMLList. The contents of each can be accessed and manipulated as needed utilizing the public API (properties and methods) corresponding to the supporting ActionScript class – XML or XMLList.

XML was designed to support the transport, storage and description of hierarchical data using custom markup. The XML class contains methods and properties for working with a single, well-formed XML document.

As one might guess, an XMLList is simply a list of XML objects. Looking closely at the methods of the XML class, you’ll notice that many operations potentially result in a match against multiple XML nodes (i.e. attributes(), children(), descendants(), etc). With each matching node representing the format of a well-formed XML document, it makes sense to provide a class designed to hold one or more XML objects. That class is the XMLList class.

Note: XML and XMLList classes support E4X operations that may also return a list of XML objects (XMLList). This includes shorthand operations such as (.) or (..) used for retrieving children or descendant nodes respectively or predicate filtering.As a Flex developer, your intent, most likely, is to eventually render some, if not all, of your data on the screen. Whether your data is linear or hierarchical in nature, Flex provides the following “data provider” components suited for the task at hand:

List-based controls (DataGrid, List, TileList and HorizontalList) for linear or flat data structures (Arrays)

Trees and menu-based controls (Tree, Menu, MenuBar, PopUpMenuButton) for hierarchical data structures (XML or XMLList)

Data provider components require a reference to the data for display. This reference is captured in the dataProvider property of the data provider component instance.

<!-- MXML -->

<List id=”myList” dataProvider=”{myArray}” /><Tree id=”myTree” dataProvider=”{myXMLList}” />

// ActionScript

var myList:List = new List();myList.dataProvider = myArray;

var myTree:Tree = new Tree();myTree.dataProvider = myXMLList; At first glance, this appears to be an acceptable use of data binding. However, using raw data objects (Array, XML and XMLList) as a data provider for a UI control is not considered a best practice.

Instead, it is recommended that collections are used in place of raw data objects for the following reasons: Changes to the data stored in a collection are immediately reflected in the UI control Collections provide a "view" of the underlying data that can be sorted or filtered

Therefore, an ArrayCollection should be used in place of an Array (see related blog entry) and an XMLListCollection should stand in for an XMLList object.

Page 31: 10 Things a Good Flex Developer Should Know

XMLListCollection

Similar to an ArrayCollection, XMLListCollection extends the ListCollectionView class which implements the ICollectionView and IList interfaces. 3 members of the ICollectionView interface play an integral role in the implementing class' ability to support data binding:

2 methods: addEventListener() & dispatchEvent() 1 event: collectionChange

When the [Bindable] metadata tag is used with a collection, Flex generates code behind the scenes required to make the collection "bindable". This code is dependent on the ability to register an event handler triggered by a event dispatched when the data object changes (aka event listener). By extending ListCollectionView which implements ICollectionView, XMLListCollection becomes an eligible participant in the data binding game.

For a more detailed look at the guts of data binding, check out Michael Labriola's presentation entitled Diving in the Data Binding Waters

To create an XMLListCollection, 3 techniques are available:

// creating an empty XMLListCollectionprivate var myXMLListCollection:XMLListCollection = new XMLListCollection();

// passing an existing XMLList into an XMLListCollection via the constructorprivate var myXMLListCollection:XMLListCollection = new XMLListCollection(myXMLList);

// assigning an existing XMLList to the source property of an XMLListCollectionprivate var myXMLListCollection:XMLListCollection = new XMLListCollection();myXMLListCollection.source = myXMLList; After being "wrapped" by an XMLListCollection, the majority of the XMLList methods are still available including (but not limited to):

- attributes- child- children- copy- descendants- elements

Note: E4X shorthand operations also apply to an XMLListCollectionBut now your plain old hierarchical data storage container (XMLList) has been infused with new powers including data binding (as mentioned previously) and new properties / methods.

New properties:

- filterfunction- sort

New methods:

- addAll- addAllAt- addEventListener- addItem

Page 32: 10 Things a Good Flex Developer Should Know

- addItemAt- getItemAt- getItemIndex- refresh (for use with filterfunction and sort properties)

Note: These are the same properties and methods employed by an ArrayCollection. Sharing the same super class (ListViewCollection), ArrayCollection and XMLListCollection behave in a very similar manner, however, it is typically the UI control that will dictate the type of collection required as a data provider. Remember, list-based UI controls (DataGrid, List, TileList and HorizontalList) require linear (or flat) data structures (ArrayCollection) while tree or menu-based controls (Tree, Menu, MenuBar, PopUpMenuButton) require hierarchical data structures (XMLListCollection).In addition to the enhanced API provided by a collection, wrapping an XMLList inside an XMLListCollection provides 2 very powerful features:

1. filtering 2. sorting

A collection provides a "view" of the underlying data (Array or XMLList) that can be filtered and sorted without affecting the underlying data. It is this "view" in which UI controls are bound to. Alter the "view" using the filterfunction or sort properties along with the refresh() method and the changes are immediately reflected in your UI control.

Flex Examples - Creating a Custom Visual Component

Posted by Jeremy Mitchell The Flex SDK includes a compiler, debugger, profiler and a class library. The Flex Class Library is commonly referred to as the Flex Framework and includes hundreds of ActionScript classes and interfaces used to develop Flex applications.

The classes serve as the basis for Flex's visual and non-visual components:

Visual component classes: Containers for layout (HBox, VBox, Canvas, Panel) and navigation (Accordion, Tab Navigator,

ViewStack) Controls for data input (TextInput, TextArea, DateField, CheckBox, etc) and data presentation (List,

DataGrid, Tree, etc) Controls for user interaction (Button, LinkBar, etc) Components for charting (BubbleChart, LineChart, PieChart, etc)

Non-visual component classes: Components for data access (HTTPService, WebService, RemoteObject, etc) Components for data collection (ArrayCollection, XMLListCollection) Components for data validation (EmailValidator, NumberValidator, RegExpValidator, etc) and data

formatting (DateFormatter, PhoneFormatter, etc) Components for animation effects and state transitions (Move, Resize, Fade, etc) Skin and Style classes (Border, ProgrammaticSkin, CSSStyleDeclaration) Manager classes (BrowserManager, HistoryManager, CursorManager, LayoutManager, etc) Utility classes (ArrayUtil, ColorUtil, GraphicsUtil, etc) Language feature support classes (BindingUtils, ChangeWatcher, etc)

Shipped with the Flex SDK, most of these classes produce "built-in" components available for use immediately. Utilization only requires instantiation and an understanding of each component's API (the accessible properties and methods and the applicable events, styles and effects). API details are found in the Flex Language

Page 33: 10 Things a Good Flex Developer Should Know

Reference and exposed through Flex Builder's code completion (hit control-space bar while in an MXML tag or after a dot in ActionScript when using dot notation to see the accessible members of the class).

Note: Some of these classes are created for you at application start up (i.e. Manager classes) or do not require instantiation for use (i.e. Utility classes).The following example demonstrates utilization of a built-in Button component by way of a public property (label) and style (color) while registering a handler on the buttonDown event (aka event listener).

<mx:Button id="myButton" label="Hello" color="0xFF0000" buttonDown="doSomething(event)" /> 90% of your Flex development will require built-in components. The rest will require custom components.

Note: The remainder of this entry will focus on visual components. Visual components eligible for participation in the Flex Framework descend from the UIComponent class which descends from the DisplayObject class. The DisplayObject class is the base class for all objects that can be placed on the display list.

A custom visual component is required in the following scenarios: 1. You want to customize the functionality of a built-in visual component to meet your specific

requirements2. Nothing in the Flex Class Library comes close to the functionality you want so you need to build a

custom visual component from scratch3. You want to package multiple components into one custom visual component for the sake of modularity

and/or reusability

We'll cover each scenario below:

Scenario #1: You want to customize the functionality of a built-in visual component to meet your specific requirements

In many instances, built-in components satisfy most of your needs. For example, you may need a control to render data as a vertical list while capturing the value of an HSlider's value property. The HSlider's value property will help determine the font color of each item in the vertical list.

Note: This custom component was built in a previous blog entry entitled Flex Examples - Item Renderers in Practice to demonstrate a technique used to facilitate real-time communication between a list-based control's item renderer and an external component.

Extending the capabilities of a built-in component

Since Flex already provides a control capable of rendering data as a vertical list - List, we'll start with that and extend the functionality to include our new property. This can be done in MXML or ActionScript.

Note: Extending an existing class for the purpose of customization follows a fundamental object-oriented design principle - The Open-Closed Principle. This principle says that classes should be open for extension, but closed for modification.First, navigate to the desired package (directory) in Flex Builder where you'd like your custom component to reside.

Page 34: 10 Things a Good Flex Developer Should Know

If using MXML...

From the context menu (right-click), select File > New MXML Component. Set the 'Based on' field to 'List' and give your MXML component a name starting with a capital letter (to distinguish classes from objects, classes start with a capital letter whereas objects (instances of a class) do not).

The content of your new MXML component is as follows:

<?xml version="1.0" encoding="utf-8"?><mx:List xmlns:mx="http://www.adobe.com/2006/mxml">    </mx:List> We're using a List as our base class (so List is our root tag), and we're going to extend its capabilities by adding any properties and methods we see fit. Here we will add a new property to the List control exposed publicly through a getter and setter.

<?xml version="1.0" encoding="utf-8"?><mx:List xmlns:mx="http://www.adobe.com/2006/mxml">

    <mx:Script>        <![CDATA[            private var _newProperty:Number;                        // property accessible via a public getter & setter            // make it bindable if you anticipate its use as the source of a data binding            [Bindable]            public function get newProperty():Number{                return _newProperty;            }                        public function set newProperty(value:Number):void {                _newProperty = value;            }        ]]>    </mx:Script>    </mx:List>

If using ActionScript...

Page 35: 10 Things a Good Flex Developer Should Know

Again, from the context menu select File > New ActionScript Class. Set the 'Superclass' field to mx.controls.List (or hit browse and type in List) and give your ActionScript class a name starting with a capital letter. Flex Builder will create your class with the following contents:

package comps{    import mx.controls.List;

    public class MyList extends List    {        public function MyList()        {            super();        }            }} List is the base class we'd like to extend. Our new class (MyList) inherits the capabilities of a basic List control by extending it while providing an opportunity to customize the properties and methods to meet our needs.

package comps{    import mx.controls.List;

    public class MyList extends List    {        private var _newProperty:Number; // new property                public function MyList()        {            super();        }

        // getter and setter for our new property marked as bindable        [Bindable]               public function get newProperty():Number {            return _newProperty;        }                public function set newProperty(value:Number):void {            _newProperty= value;        }            }} Now we can create an instance of our new, customized list and utilize our new property.

<comps:MyList newProperty="2" /> Or, we can use it as we intended based on our previous requirements.

Page 36: 10 Things a Good Flex Developer Should Know

<!-- Bind to the HSlider's value property --><comps:MyList newProperty="{myHSlider.value}" />

Overriding the behavior of a built-in component

In addition to extending the capabilities of a built-in component, we can change the way it currently behaves.

For example, a Label component is a perfect candidate for an Item Renderer. However, we may want to change the Label's text color when our Label is used as an Item Renderer and certain conditions apply.

Looking closely at the Label class' source file (ctrl-click a Label tag in Flex Builder) and knowing a thing or two about Item Renderers, we settle on the set data method. This method passes the data for an item to the Item Renderer.

Note: The Label class is eligible for item rendering based on the implementation of the IDataRenderer interface which enforces implementation of a data property getter and setter method. Without these methods, there would be no way to pass an item's data to the Label instance.We would like to add some additional logic to the set method to meet our requirements, therefore, we will extend the Label class and override this existing method.

<!--- MyLabel.mxml used as an Item Renderer --->

<?xml version="1.0" encoding="utf-8"?><mx:Label xmlns:mx="http://www.adobe.com/2006/mxml"    text="{data.name + ' (' + data.age + ')'}">    <mx:Script>        <![CDATA[                        override public function set data(value:Object):void {                // this is critical since we only want to inject additional logic                super.data = value;                 // new behavior                var minAge:Number = 40;                if (data.age < minAge) {                    setStyle("color",0xFF0000);                } else {                    setStyle("color",0x000000);                }            }        ]]>    </mx:Script>    </mx:Label> Note: In most cases, it is critical that we preserve the base class' implementation of the method we wish to override. Therefore, in this example, we need to call super.data.9 times out of 10, you can enhance a built-in component by extending or modifying its capabilities to fit your needs. Extend an existing class, add a new property or method, override an existing method, or even add new styles, effects or events....

Scenario #2: Nothing in the Flex Class Library comes close to the functionality you want so you need to build a custom visual component from scratch

Page 37: 10 Things a Good Flex Developer Should Know

On occasion, you may have the need to create a component from scratch. This approach is warranted when nothing is gained by extending the functionality of an existing, built-in component (container or control).

For example, you may choose to extend a VBox when you wish to "contain" child components while inheriting the built-in top-to-bottom layout capabilities. However, if layout for your component is dynamic and determined by a style setting, the layout rules of a VBox may not always apply.

As mentioned previously, all visual components eligible for participation in the Flex Framework descend from the UIComponent class. The UIComponent class implements 5 methods required of a visual component. These methods are known as the component lifecycle methods and they include:

1. createChildren2. commitProperties3. measure4. layoutChrome5. updateDisplayList

The Flex Framework depends on these methods and every visual Flex component implements them directly or indirectly (through class inheritance).

Each method plays a particular role and makes a component unique to itself. For components added to the display list, these methods are called by the Flex Framework on application startup and may be called during the lifetime of a component as needed.

createChildren()

Implementation of the createChildren method is required if the visual component is a composite component. Composite components contain child objects. The createChildren method is only called once when the component is added to the display list.

commitProperties()

By coordinating property changes and ensuring expensive calculations are not performed unnecessarily, the commitProperties method can help developers achieve optimal application performance.

measure()

The logic required to determine the custom component's default size and, optionally, default minimum size is contained within the measure method.

layoutChrome()

Container components utilize the layoutChrome method to define border area.

updateDisplayList()

The sizing and positioning of child components is calculated within the updateDisplayList method.

For more information, Adobe has provided a more detailed description of each component lifecycle method.

The following example demonstrates the use of a custom visual component. This component consists of 2 child objects - a TextArea and a Button. The TextArea can be enabled/disabled programatically or by clicking the

Page 38: 10 Things a Good Flex Developer Should Know

button. The layout can also be changed at runtime using the radio buttons.

View source is also enabled to provide insight into the structure of the custom component.

Scenario #3: You want to package multiple components into one custom visual component for the sake of modularity and/or reusability

Rather than creating an application consisting of one monolithic file, it is common practice to break an application down into pieces. This technique promotes code reuse and better organization.

Creating custom components to encapsulate distinct application views

Most Flex applications contain multiple views. A view consists of the components required to satisfy a particular task or objective. Each view could be constructed quite easily in the main application file. For example, the following application consist of 2 views - a Login View and a Search View.

<?xml version="1.0" encoding="utf-8"?><mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"    layout="vertical">        <mx:Script>        <![CDATA[            private function login(event:MouseEvent):void {                vs.selectedIndex = 1;            }        ]]>    </mx:Script>

    <mx:ViewStack id="vs"> <!-- navigation containers typically manage views -->            <!-- Login View -->                <mx:Panel title="Login">            <mx:Form>                <mx:FormItem label="Username">                    <mx:TextInput/>                </mx:FormItem>                <mx:FormItem label="Password">                    <mx:TextInput/>                </mx:FormItem>            </mx:Form>            <mx:ControlBar>                <mx:Button label="Login" click="login(event)"/>            </mx:ControlBar>        </mx:Panel>                <!-- Search View -->                <mx:VBox>            <mx:HBox>                <mx:TextInput/>

Page 39: 10 Things a Good Flex Developer Should Know

                <mx:Button label="Search"/>            </mx:HBox>            <mx:DataGrid/>        </mx:VBox>            </mx:>    </mx:Application> However, as the application inevitably grows, so does the amount of code in the main application file. Before you know it, it is hard to tell where one view ends and another one begins.

To prevent duplicate code and unwieldy file sizes, consider breaking your application into pieces designed to perform a singular task (for example, "login" is a task represented by a unique view and warrants its own component). This is done by creating custom components like we did before.

<?xml version="1.0" encoding="utf-8"?><mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:views="views.*"    layout="vertical">        <mx:Script>        <![CDATA[            private function login(event:Event):void {                vs.selectedIndex = 1; // navigate to the search view            }        ]]>    </mx:Script>

    <mx:ViewStack id="vs">            <!-- Login View -->                <views:LoginView loggedIn="login(event)"/> <!-- custom component -->                <!-- Search View -->                <views:SearchView/> <!-- custom component -->            </mx:ViewStack>    </mx:Application>

<!-- LoginView.mxml extends Panel -->

<?xml version="1.0" encoding="utf-8"?><mx:Panel xmlns:mx="http://www.adobe.com/2006/mxml">

    <!-- this component dispatches a loggedin event -->    <!-- that you can now listen for in MXML or ActionScript -->    <mx:Metadata>        [Event(name="loggedIn", type="flash.events.Event")]

Page 40: 10 Things a Good Flex Developer Should Know

    </mx:Metadata>

    <mx:Form>        <mx:FormItem label="Username">            <mx:TextInput/>        </mx:FormItem>        <mx:FormItem label="Password">            <mx:TextInput/>        </mx:FormItem>    </mx:Form>    <mx:ControlBar>        <mx:Button label="Login" click="dispatchEvent(new Event('loggedIn'))"/>    </mx:ControlBar>    </mx:Panel>

<!-- SearchView.mxml extends VBox -->

<?xml version="1.0" encoding="utf-8"?><mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml">    <mx:HBox>        <mx:TextInput/>        <mx:Button label="Search"/>    </mx:HBox>    <mx:DataGrid/></mx:VBox> This becomes essential as your views become more complex (i.e. more internal (child) components, view states, events, etc).

Note: Because our Login view was packaged into a LoginView component, access to the application's login method was no longer available. Communication between components should always be accomplished using events, therefore, the LoginView component now dispatches an event. A listener is created in the main application file to handle the event.<views:LoginView loggedIn="login(event)"/> In this example, we've created two custom components (LoginView and SearchView) for the purpose of packaging multiple components together. We didn't reduce the amout of code but we did reduce clutter, and if we want, we can reuse these components without copying/pasting code.

Whether you're looking to extend the capabilities of an existing component, create a component from scratch or group components into views, Flex provides the mechanism to do so. Have fun!

Event Propagation in Flex/ActionScript 3

Posted by Jeff Krueger I came across a question in an interview the other day about event propagation and I thought it would be a good topic to blog about. Most of the time you never need to know the details of event propagation in Flex. All you normally do is setup your event listener inline on the component.

<mx:Button id="myButton2" label="test" click="myButton_click(event)"/>  or by adding it explicitly to the component via ActionScript.

Page 41: 10 Things a Good Flex Developer Should Know

myButton.addEventListener(MouseEvent.Click, myButton_click); Then you put your code in your eventListener function and you are done. But what is truly going on when the user clicks the button? Event propagation is made up of 3 parts.

Capturing Targeting Bubbling

Capturing and Bubbling are similar but work in opposite directions. When a user clicks on a button the capturing phase begins working its way down the DisplayList looking for items listening for the given event type with the useCapture option set to true. By default, useCapture is set to false. When it is set to false, the eventListener will be called during the bubbling phase. To add an eventListener for the capture phase you have to use the second method mentioned above passing in true for the third parameter. For example:

myButton.addEventListener(MouseEvent.CLICK, myButton_click, true);  When the capturing phase hits the point where the object from the displayList being evaluated is the one that initiated the event, it changes to the Targeting phase. This is known because the target and currentTarget variables will equal. This is explained more later. Once this is reached then the BubblingPhase begins for events that support bubbling.

During the BubblingPhase the displayList is walked in reverse and the system is looking for eventListeners for this event with the useCapture set to false (the default value). When they are found, those eventListeners are executed.

During both Capturing and Bubbling the event object has two variables that are important. One is target and the other is currentTarget. Target is always the object that initiated the event. The currentTarget is always the current item in the displayList being processed. You should always use currentTarget in your eventListener functions. That will always be the object that the eventListener is associated to. For example, if the user clicks on the text of the button. The target will be set to a label class since that is the sub component that was truly clicked on and initiated the event process. But when your eventListener function, attached to the button, is executed the currentTarget will be the button and the target will still be the label.

At any point in the Capturing or Bubbling process you can stop the process from continuing to the next item in the display list. There are two options, stopPropagation and stopImmediatePropagation. The difference between the two functions is that stopPropagation will allow other items at the same level in the displayList to receive the event, where the stopImmediatePropagation function stops right then.

Understanding the event propagation within Flex provides many options. You can control what components get to see events. You can change the behavior of items, mostly done when you are building custom components. You can reduce code by putting shared code in a common click function at a higher level. And, of course, the more you understand about how components interact the better custom components you can build.

Flex Examples - Creating a Custom Event

Posted by Jeremy Mitchell Flex applications consist of a component hierarchy starting with the Application root. Components are built-in or custom.

Page 42: 10 Things a Good Flex Developer Should Know

Interaction between components may occur down the component hierarchy (parent to child) or up (child to parent).

When a parent component interacts with a child component, the parent utilizes the child component's interface (API). This interface includes the component's public properties and methods.

For example, a parent component may hide a child component by setting its visible property to false.

<!-- parent component --><mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"> 

    <mx:Script>        <![CDATA[            private function doSomething(event:MouseEvent):void {                lbl.visible = false; // parent (Application) interacting with child (Label)            }        ]]>    </mx:Script>        <!-- child component -->    <mx:Label id="lbl" text="Hello there"/>         <!-- child component -->    <mx:Button label="Hide Label" click="doSomething(event)"/>    </mx:Application> Note: The Label's visible property is actually marked private but is publicly exposed through an implicit getter and setter.Conversely, when a component wants to interact with a parent (or ancestor) component, it does so by dispatching events. Events are dispatched to signify an occurrence has taken place and include the details of the occurrence wrapped inside an event object.

Components may express an interest in a particular event by registering an event listener. Event listeners map an event to a method. This method is referred to as an event handler and is designed to perform one or more actions in response to an event.

Because an event (built-in or custom) propagates down through the display hierarchy during the Capturing

Page 43: 10 Things a Good Flex Developer Should Know

phase of the event flow and back up during the Bubbling phase, ancestor components have two opportunities to register event listeners.

Note: Events do not bubble by default. All events extend the flash.events.Event class which requires 3 constructor arguments (type, bubbles and cancelable). Set bubbles to true and override the clone method to activate event bubbling.In addition to the details of the event (target, currentTarget, type, eventPhase, etc), custom event objects can carry a "payload" used to transfer data. The payload is nothing more than a storage variable declared as a property of the event object.

In this short video, I will create a custom event designed to carry user information (username / password) captured when the user logs in.

Correction: In the video, I failed to override the clone method. Without overriding the clone method, a custom event will not be capable of bubbling.

View the source code of the custom event example.

After watching the video, it may still not be obvious why this approach is considered a best practice. Following the principles of encapsulation, we want our components to represent a "black box". We interact with a component via its public interface (API) and it broadcasts information about itself using events. If you find the event and the information it contains to be interesting, listen for the event and act on it.

Interaction between components in this fashion promotes loose coupling which ultimately provides greater flexibility.

Flex Principles - Application Development

Posted by Jeremy Mitchell I became a developer so I could build things. I was tired of attending misguided meetings, writing requirements documents that nobody read and talking about what a group of uninformed individuals thought needed to be built. I just wanted to build cool stuff and provide immediate value.

Unfortunately, I quickly learned that application development involves more than writing code. Successful application development is a process involving multiple phases and multiple participants with a range of skills.

To succeed, it’s important to adopt a development process that works for your team, your company and the types of projects you’re involved with. Without a process, the risk of project failure is high. The ideal process doesn’t get in your way, covers only the necessary bases and gives you the best chance for success.

In my experience, I’ve found a "front-end first" approach coupled with small design and development cycles (iterations) to be enjoyable, effective and efficient.

In this blog entry, I will outline the process, tools and platform I use to define, build and deploy small to medium-sized rich internet applications (RIA) using Adobe Flex, ColdFusion and MySQL. This process is neither revolutionary nor specific to RIA development. In fact, many of the steps I follow may also be applied to traditional web development (HTML, CSS, JavaScript, PHP, ColdFusion, .NET, etc).

In addition, to effectively demonstrate the process, I will reference the project artifacts created for each phase of a recently completed Flex project: FlexWire Demo App.

Page 44: 10 Things a Good Flex Developer Should Know

Process

The steps involved to create an application cross 5 phases:1. Application planning 2. Application user interface (UI) layout and structure 3. Application design and development 4. Application testing 5. Application deployment

Application Planning

Entrance criteria: An idea, a directive, an opportunity, a problem, whatever...

Tool(s): Project Profile Form

It’s difficult to create anything without a basic understanding of the business objectives. During the planning phase, it’s important to identify these objectives at a high-level.

Step#1: Define the business objectives

Example: Provide a mechanism to organize and distribute related news articles to newsletter subscribers via email.To satisfy the business objectives, an application must support a range of user and system scenarios. User scenarios help define the functionality required of an application from a user perspective. Think about the tasks involved in achieving the business objectives. These become your user scenarios.

Step#2: Define user scenarios

It is important to group or categorize user scenarios in a logical manner to minimize confusion and support the UI layout and structure phase. These categories may turn out to be synonymous with user roles.

Example: Manage Newsletters (user role) - Create Newsletter, Modify Newsletter, Delete NewsletterExit criteria: Completed Project Profile Form

Application UI layout and structure

Tool(s): Balsamiq Mockups, writemaps.com

After the planning phase, we should have a good understanding of the application’s purpose. However, the UI layout and structure phase will help us flesh out additional requirements while designing each view of the UI.

A view represents a unique combination of Flex UI components (containers and controls) and business logic utilized to perform a group of related tasks. By organizing our user scenarios into logical groupings (i.e. user roles) during the planning phase, the characteristics of each UI view should be somewhat evident.

Preliminary design of each view is attained through mockups. Iterations occur until each mockup accurately reflects the layout and structure of the proposed view and visually demonstrates the functionality required to perform the desired tasks.

Page 45: 10 Things a Good Flex Developer Should Know

Step#1: Create UI mockups

By following this approach, we design the UI while uncovering functional requirements overlooked in the planning phase. New user scenarios discovered during this step should be documented.

Each mockup should represent a unique view of your UI. However, as the number of permutations increase (through view states or navigation containers), this may not be feasible. Use your best judgment.

Example: FlexWire mockups - newsletters view, issues view, articles view, subscriptions view, categories view, roles view, templates viewNote: It may be necessary to supplement your mockups with notes to provide details that may be difficult to capture in a visual mockup. For example: "The contents of ComboBox #2 (US Cities) depend on the selectedValue of ComboBox #1 (US States)."

In addition to UI mockups, it is important to discuss the relationship of each view to one another. This can often be accomplished by building a simple wireframe. Wireframes may also be used to dictate application workflow if applicable.

Step#2: Create application wireframe

Once a wireframe is complete with the supporting mockups, we will have a solid understanding of the project’s scope and the flow of the application. Only now can an accurate development estimate be derived.

Example: FlexWire wireframeExit criteria: wireframe, mockups

Application design and development

Tool(s): CFEclipse, Flex Builder, Subclipse, MySQL Admin, FlexUnit, MXUnit, Stax.net

Additional Resources: Tour De Flex, Flex Style Explorer, Flex Skins, Flex Language Reference, Cairngorm, Transfer, ColdSpring

Thanks to our wireframe and mockups, we know what needs to be created and how the features are organized within the application. However, before any code can be written, a suitable application platform must be in place.

Step#1: Set up your application platform

A suitable platform includes a separate environment to support your development, testing and production activities. At a minimum, I would recommend 3 environments:

1. Development environment (created locally for each designer / developer) 2. Staging (testing) environment 3. Production environment

To maintain consistent and predictable results, it is important to ensure that each environment is identical from a configuration, code and data perspective.

Note: Environment setup includes, among other things, configuration of a web server, application server and a database server. Initial setup, frequent synchronization and ongoing maintenance of each environment can prove to be very time consuming. I prefer to offload these activities if possible. Maybe you have a server engineer at your disposal. If not, I've found Stax.net to be a great option for quickly and easily setting up and

Page 46: 10 Things a Good Flex Developer Should Know

replicating Java server configurations (including ColdFusion) across multiple environments. Stax is a fully-managed platform deployed and hosted on top of Amazon's EC2 cloud computing service.

With each environment in place, a source code repository is required. I won't go into the benefits of source control, however, suffice it to say that without source control you are taking an unnecessary risk while limiting developer productivity. Whether you are working with a team or not, setup a Subversion (SVN) repository and start importing source code from the start.

Note: For RIA development, it is only necessary to import source code files into your SVN repository. The files generated from a Flex release build (release build artifacts such as the application SWF and the wrapper HTML) should not be captured in source control.

With a platform in place, a foundation for development must be established. Architectural frameworks provide a starting point for development and enforce consistent development practices. Many architectural frameworks also support an MVC architecture. MVC is a standard for building RIA applications.

Step#2: Establish an architectural framework

Without a framework, developers can spend a lot of time on the “plumbing” of an application. This is no longer necessary as there are a number of free solutions available. For RIA development, I choose to use Cairngorm on the client-side and ColdSpring & Transfer on the server-side.

With a framework in place, we are ready to finally write some code.

Step#3: Architect and design the user interface (the V in MVC)

Sticking with the "front-end first" approach, build the UI layout and structure by replicating each mockup in Flex using MXML and ActionScript. You'll find that most of the code written in this step will include MXML as it is the preferred method for defining application layout and structure. Also, apply any necessary UI effects and transitions.

Page 47: 10 Things a Good Flex Developer Should Know

Once the layout and structure of the UI is in place, style and/or skin the user interface via CSS and/or ActionScript. This may involve multiple iterations to secure the right look and feel.

UI development should occur within the development branch of SVN (typically SVN trunk) - specifically in trunk >> Flex according to this example.

While building the UI, additional requirements may be uncovered. This is unavoidable. Be sure to document them as they may have an impact on your delivery schedule.

Note: During this step, use of ActionScript should be limited to view logic (i.e. navigating and/or changing view states) and/or styling/skinning. Business logic should be implemented during the next step. Also, in some instances, your UI may require data to achieve the proper look and feel. Hard-coded data structures can help populate data provider controls (i.e. ComboBox, DataGrid, List, Tree, etc) with little effort.

Once the user interface is in place and approval has been obtained, it is time to build out the features of the application.

Step#4: Develop and unit test application features (the M&C in MVC and the application services (the service layer))

Each user scenario defined during the planning phase or discovered subsequently represents a feature of your application. Features should be packaged into short iteration cycles (2 weeks or less) and prioritized. It’s important to identify dependencies as well when determining iteration schedules. For example, Feature B depends on Feature A.

With an iteration schedule in place, feature development can begin. Feature development typically requires use of:

1. ActionScript and MXML for the controller and model layer within the Flex client2. ColdFusion (or any other server-side scripting language) and SQL for the application service layer

(Note: Transfer will take care of the majority, if not all, of the SQL required to perform basic CRUD operations)

3. SQL in the form of DDL (Data Definition Language) and DML (Data Manipulation Language) required to build and populate the database

Each feature will include a set of classes - ActionScript classes and/or ColdFusion classes (CFCs). A unit test for each class is required to validate expected behavior. It is much easier to identify and resolve errors at the class level rather than the feature or application level. FlexUnit and MXUnit can help with ActionScript and ColdFusion unit testing respectively. Unit tests should be performed locally in the development environment. Once all unit tests are successful, "developer" testing should occur to verify the overall behavior of each new feature.

The completion of each iteration delivers a set of fully-functional features from the UI all the way to the database. At this point, code should be copied from the development branch (SVN trunk) to a new branch

Page 48: 10 Things a Good Flex Developer Should Know

created specifically for the current iteration. The contents of this new branch should be deployed to the staging environment for additional testing (see next phase).

Each development cycle (iteration) yields a new SVN branch. For example:

Exit criteria: MXML, ActionScript, CSS, CFML, SQL, DDL / DML committed to SVN trunk and copied to an iteration branch; Unit tests and results

Application testing

Tool(s): FlexMonkey, Selenium-Flex API, Trac

A former boss of mine once asked me why testing was necessary. He told me "if you built it right in the first place, testing was unnecessary and only a waste of time." Technically, he's correct. Unfortunately, most (if not all) developers rarely get everything "right" out of the gate so I'll dismiss his ignorant comment.

Although each class has been tested at an atomic level via unit testing and the functionality of each feature has been verified, unforeseen behavior can and does occur once ALL of the pieces are put together.

Test each feature in the context of the entire application in the staging environment. Also, regression testing is often required to ensure that new functionality does not break existing functionality. Regression testing can be time-consuming and mind-numbing. Therefore, automated test tools are essential. Look into FlexMonkey and the Selenium-Flex API.

Bugs found in the staging environment will need to be logged in Trac and fixed immediately. Fixes should be applied directly to the code found in the iteration branch. Once bug fixes are verified and testing of the iteration is complete, merge the changes back into the development branch and create an SVN "tag" (snapshot) representing a clean and functional version of the iteration branch. Each tag represents a candidate for release and, if appropriate, may be deployed to production (see next phase).

Note: Development should never occur within a tag.

Staging is also a good place to perform User Acceptance Testing (UAT) if desired.

Page 49: 10 Things a Good Flex Developer Should Know

Exit criteria: Test cases and results; a tag for each successfully-tested iteration; bug fixes merged back into the development branch (SVN trunk)

Application deployment

Tool(s): Ant, Maven

With each iteration complete and tested, it is time to deploy your application to production. Automation of this phase can save time and minimize errors. Build scripts (ANT or Maven) can perform the following deployment activities:

Checkout code from the appropriate SVN tag Filter out irrelevant files (i.e. SVN core files) Run SQL scripts (DDL and/or DML) to create the required database structure and generate seed data Copy/Move files to the production server

Exit criteria: A fully-functional application inline with the user requirements, deployed to a production environment, and backed-up in a source code repository

Afterthought: In an attempt to redefine the designer / developer workflow, Adobe is proposing an approach to application layout and design involving a designer's use of existing Adobe tools (Photoshop, Illustrator, Fireworks) to generate the design and layout of each view and, with the release of Flash Catalyst, supplement these design assets with visual effects and transitions. The output being the front-end of a Flex application inline with the designers vision, ready for development and abstracted from the application code in the form of design components. I have yet to explore this approach and currently rely on mockups, MXML, publicly-available themes and styles / skins implemented through conventional CSS and ActionScript to create the layout, structure and style of a Flex application. See related blog entry – Application Design.