Adobe Flex 3 Help

Creating deferred components

When you set a container's creationPolicy property to none, components declared as MXML tags inside that container are not created. Instead, objects that describe those components are added to an Array. These objects are called descriptors. You can use the createComponentsFromDescriptors() method to manually instantiate those components. This method is defined on the Container base class.

Using the createComponentsFromDescriptors() method

You use the createComponentsFromDescriptors() method of a container to create all the children of a container at one time.

The createComponentsFromDescriptors() method has the following signature:

container.createComponentsFromDescriptors(recurse:Boolean):Boolean

The recurse argument determines whether Flex should recursively instantiate children of the components. Set the parameter to true to instantiate children of the components, or false to not instantiate the children. The default value is false.

On a single-view container, calling the createComponentsFromDescriptors() method instantiates all controls in that container, regardless of the value of the creationPolicy property.

In navigator containers, if you set the creationPolicy property to all, you do not have to call the createComponentsFromDescriptors() method, because the container creates all controls in all views of the container. If you set the creationPolicy property to none or auto, calling the createComponentsFromDescriptors() method creates only the current view's controls and their descendents.

Another common usage is to set the navigator container's creationPolicy property to auto. You can then call navigator.getChildAt(n).createComponentsFromDescriptors() to explicitly create the children of the n-th view.

The following example does not instantiate any of the buttons in the HBox container when the application starts up, but does when the user changes the value of the creationPolicy property. The user initiates this change by selecting all from the drop-down list.

<?xml version="1.0"?>
<!-- layoutPerformance/ChangePolicy.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="appInit()">
    <mx:Script><![CDATA[
        [Bindable]
        public var p:String;
    
        private function appInit():void {
            p = policy.selectedItem.toString();
        }

        private function changePolicy():void {
            var polType:String = policy.value.toString();
            hb.creationPolicy = polType;    
            if (polType == "none") {
                // do nothing
            } else if (polType == "all") {
                hb.createComponentsFromDescriptors();
            }
        }
    ]]></mx:Script>
    <mx:ComboBox id="policy" close="p=String(policy.selectedItem);changePolicy();">
        <mx:dataProvider>
            <mx:Array>
                <mx:String>none</mx:String>
                <mx:String>all</mx:String>
            </mx:Array>
        </mx:dataProvider>
    </mx:ComboBox>

    <mx:Panel title="Creation Policy" id="hb" creationPolicy="none">
        <mx:Button label="B1" width="50" y="0" x="0"/>
        <mx:Button label="B2" width="50" y="0" x="75"/>
        <mx:Button label="B3" width="50" y="0" x="150"/>
    </mx:Panel>
    
    <mx:Label text="CreationPolicy: {p}"/>
    
</mx:Application>

The executing SWF file for the previous example is shown below:

Using the childDescriptors property

When a Flex application starts, Flex creates an object of type Object that describes each MXML component. These objects contain information about the component's name, type, and properties set in the object's MXML tag. Flex adds these objects to an Array that each container maintains. For example, applications with two Canvas containers have an Array with objects that describe the Canvas containers. Those containers, in turn, have an Array with objects that describe their children.

Each object in the Array is an object of type ComponentDescriptor. You can access this Array by using a container's childDescriptors property, and use a zero-indexed value to identify the descriptor. All containers have a childDescriptors property.

Depending on the value of the creationPolicy property, Flex immediately begins instantiating controls inside the containers or it defers their instantiation. If instantiation is deferred, you can use the properties of this Array to access the ComponentDescriptor of each component and create that object at a specified time.

The childDescriptors property points to an Array of objects, so you can use Array functions, such as length, to iterate over the children, as the following example shows:

<?xml version="1.0"?>
<!-- layoutperformance/AccessChildDescriptors.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
    <mx:Script><![CDATA[
        import mx.core.ComponentDescriptor;
        import flash.utils.*;
        
        public function iterateOverChildren():void {
            // Get the number of descriptors.
            var n:int = tile.childDescriptors.length;
            for (var i:int = 0; i < n; i++) {
                var c:ComponentDescriptor = tile.childDescriptors[i];
                var d:Object = c.properties;
                
                // Log ids and types of objects in the Array.
                ta1.text += c.id + " is of type " + c.type + "\n";
                
                // Log the properties added in the MXML tag of the object.
                for (var p:String in d) {
                    ta1.text += "Property: " + p + " : " + d[p] + "\n";
                }
            }
        }
        
    ]]></mx:Script>

    <mx:Tile id="tile" creationComplete="iterateOverChildren();">
        <mx:TextInput id="myInput" text="Enter text here"/>
        <mx:Button id="myButton" label="OK" width="150"/>
    </mx:Tile>
    
    <mx:TextArea id="ta1" height="150" width="250"/>
    
</mx:Application>

The executing SWF file for the previous example is shown below:

Properties of the ComponentDescriptor include id, type, and properties. The properties property points to an object that contains the properties that were explicitly added in the MXML tag. This object does not store properties such as styles and events.

Destroying components

After you create a component, it continues to exist until the user quits the application or you detach it from its parent and the garbage collector destroys it.

To detach a component from its parent container, you can use the removeChild() or removeChildAt() methods. You can also use the removeAllChildren() method to remove all child controls from a container. Calling these methods does not immediately delete the objects from memory. If you do not have any other references to the child, Adobe® Flash® Player garbage collects it at some future point. But if you have stored a reference to that child on some other object, the child is not removed from memory.

For more information on using these methods, see the View class in the Adobe Flex Language Reference.