Wednesday, June 24, 2009

Adobe Flex 3 UI Components Lifecycle

In adobe flex 3 there are certain events that are called when a component is created.
These events are raised in the following order:

1) preInitialize: This event is raised when the component has just been created but none of the child components exist.

2) initialize: This event is raised after the component and all its children have been created but before any dimensions have been calculated.

3) creationComplete: This even is dispatched after all the component and its children have been created and after all the layout calculations have been performed.

4) applicationComplete: Dispatched after all the components of an application have been successfully created

Events 1) to 3) are dispatched in the order mentioned above for all visible components.
Note however that for components that are not visible on the screen by default, none of these events will be raised. This is because depending on the creation policy the hidden components might not exist yet.
For example in a TabNavigator only the components that are inside the default tab are created because they are visible. If you do change to another non-visible tab then Flex creates the components one by one. In that case the events mentioned above are raised.

We have created a simple example to demonstrate this. The DataGrid shows you a list of the events that have been raised during the lifecycle of the main application window. If you change to the second tab you will see additional entries in the list due to the creation of a Label UI component.

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="" layout="absolute" preinitialize="preInitialise()" initialize="initialise()" applicationComplete="applicationComplete()" creationComplete="creationComplete()" viewSourceURL="srcview/index.html">
import mx.collections.ArrayCollection;

private var eventsCalled:ArrayCollection=new ArrayCollection();

public function preInitialise():void {
eventsCalled.addItem({label:"preInitialise called",event:"preInitialise"});

public function initialise():void {
eventsCalled.addItem({label:"initialise called",event:"initialise"});

public function creationComplete():void {
eventsCalled.addItem({label:"creation complete called",event:"creationComplete"});

public function applicationComplete():void {
eventsCalled.addItem("applicationComplete called");

<mx:TabNavigator width="400" height="400">
<mx:Canvas label="tab1">
<mx:DataGrid id="datagrid" dataProvider="{eventsCalled}" top="10" left="10" width="300" />
<mx:Canvas label="tab2">
<mx:Label text="This label is created only when it is displayed" creationComplete="creationComplete();" preinitialize="preInitialise();" initialize="initialise();" />


To see this example in action click: here

You can change this behavior by setting the creationPolicy attribute, for example in the application mxml node. This attribute is only valid for containers.

There are 4 possible values for this attribute:

1) creationPolicy="auto" - the container delays creating some or all of its descendants until they are needed. This is known as deferred instantiation

2) creationPolicy="all" - the container immediately creates all its descendants even if they are not selected.

3) creationPolicy="queued" - all components inside a container are added to a creation queue. The application waits until all children of a container are created before moving to the next container.

4. creationPolicy="none" - all components inside a container are never created. Whoever decides to go with this strategy needs to manually create all items inside a container.

For example to change the behavior seen above we could set the creationPolicy="all":

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="" layout="absolute" creationPolicy="all" preinitialize="preInitialise()" initialize="initialise()" applicationComplete="applicationComplete()" creationComplete="creationComplete()" viewSourceURL="srcview/index.html">

No comments: