About MXML components

In typical applications, you do not code the entire application within a single source code file. Such an implementation makes it difficult for multiple developers to work on the project simultaneously, makes it difficult to debug, and discourages code reuse.

Instead, you develop applications by using multiple MXML and ActionScript files. This architecture promotes a modular design, code reuse, and lets multiple developers contribute to the implementation.

MXML components are MXML files that you reference by using MXML tags from within other MXML files. One of the main uses of MXML components is to extend the functionality of an existing Flex component.

For example, Flex supplies a ComboBox control that you can use as part of a form that collects address information from a customer. You can use a ComboBox to let the user select the State portion of the address from a list of the 50 states in the U.S. In an application that has multiple locations where a user can enter an address, it would be tedious to create and initialize multiple ComboBox controls with the information about all 50 states.

Instead, you create an MXML component that contains a ComboBox control with all 50 states defined within it. Then, wherever you must add a state selector to your application, you use your custom MXML component.

Creating MXML components

An application that uses MXML components includes a main MXML application file, which contains the <s:Application> root tag, and references one or more components that are defined in separate MXML and ActionScript files. Each MXML component extends an existing Flex component, or another MXML component.

You create an MXML component in an MXML file where the component’s filename becomes its MXML tag name. For example, a file named StateComboBox.mxml defines a component with the tag name of <StateComboBox>.

The root tag of an MXML component is a component tag, either a Flex component or another MXML component. The root tag specifies the namespace definitions for the component. For example, the following MXML component extends the standard Flex ComboBox control.

<?xml version="1.0"?>
<!-- createcomps_mxml/StateComboBox.mxml -->
<s:ComboBox xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:s="library://ns.adobe.com/flex/spark" 
    xmlns:mx="library://ns.adobe.com/flex/mx">

    <s:dataProvider>
        <s:ArrayList>
            <fx:String>AK</fx:String>
            <fx:String>AL</fx:String>
            <!-- Add all other states. -->
        </s:ArrayList>
    </s:dataProvider>
</s:ComboBox>

As part of its implementation, a custom MXML component can reference another custom MXML component.

The main application, or any other MXML component file, references the StateComboBox component, as the following example shows:

<?xml version="1.0"?>
<!-- createcomps_mxml/MXMLMyApplication.mxml -->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:s="library://ns.adobe.com/flex/spark" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:MyComp="*">

    <MyComp:StateComboBox/>
</s:Application>

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

In this example, the main application file includes a new namespace definition of xmlns:MyComp="*" as part of the <s:Application> tag. This namespace definition specifies the location of the MXML component. In this case, it specifies that the component is in the same directory as the main application file, or if you are using Adobe® LiveCycle™ Data Services ES, in the WEB-INF/flex/user-classes directory.

As a best practice, store your components in a subdirectory. For example, you can write this file to the myComponents directory, a subdirectory of your main application directory. For more information on the namespace, see Developing applications in MXML.

The StateComboBox.mxml file specifies the ComboBox control as its root tag, so you can reference all of the properties of the ComboBox control within the MXML tag of your custom component, or in the ActionScript specified within an <fx:Script> tag. For example, the following code specifies the maxChars property and a listener for the close event for your custom control:

<?xml version="1.0"?>
<!-- createcomps_mxml/MyApplicationProps.mxml-->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:s="library://ns.adobe.com/flex/spark" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:local="*">
    <s:layout>
        <s:VerticalLayout/>
    </s:layout>

    <fx:Script>
        <![CDATA[

            import flash.events.Event;

            private function handleCloseEvent(eventObj:Event):void {
                myTA.text="foo";
            }   
        ]]>
    </fx:Script>

    <local:StateComboBox maxChars="25" 
        close="handleCloseEvent(event);"/>
    <mx:TextArea id="myTA" />
</s:Application>

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

Limitation on the default property of the root tag

Many Flex components define a single default property. The default property is the MXML tag property that is implicit for content inside of the MXML tag if you do not explicitly specify a property. For example, consider the following MXML tag definition:

<s:SomeTag> 
    anything here 
</s:SomeTag>

If this tag defines a default property named default_property, the preceding tag definition is equivalent to the following code:

<s:SomeTag> 
    <s:default_property> 
        anything here 
    </s:default_property> 
</s:SomeTag>

However, the default property mechanism does not work for root tags of MXML components. In this situation, you must use child tags to define the default property, as the following example shows:

<?xml version="1.0"?> 
<s:SomeTag xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:s="library://ns.adobe.com/flex/spark" 
    xmlns:mx="library://ns.adobe.com/flex/halo"> 
    <s:default_property> 
        anything here 
    </s:default_property> 
</s:SomeTag>

MXML components and ActionScript classes

When you create a custom MXML component, you define a new ActionScript class where the class name corresponds to the filename of the MXML component. Your new class is a subclass of the component’s root tag, and therefore inherits all of the properties and methods of the root tag. However, because you are defining the component in MXML, many of the intricacies of creating an ActionScript class are hidden from you.

For example, in Creating MXML components, you defined the component StateComboBox.mxml by using the <s:ComboBox> tag as its root tag. Therefore, StateComboBox.mxml defines a subclass of the ComboBox class.

Creating composite MXML components

A composite MXML component is a component that contains multiple component definitions within it. To create a composite component, you specify a container as its root tag, and then add components as children of the container.

For example, the following component contains an address form created by specifying a Form container as the root tag of the component, and then defining several children of the Form container. One of the <mx:FormItem> tags contains a reference to the <MyComp:StateComboBox> tag that you created in Creating MXML components:

<?xml version="1.0"?>
<!-- createcomps_mxml/AddressForm.mxml -->
<s:Form xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:s="library://ns.adobe.com/flex/spark" 
    xmlns:mx="library://ns.adobe.com/flex/mx"
    xmlns:MyComp="*">

    <s:FormItem label="NameField">
        <s:TextInput/>
    </s:FormItem>

    <s:FormItem label="Street">
        <s:TextInput/>
    </s:FormItem>

    <s:FormItem label="City" > 
        <s:TextInput/>
    </s:FormItem>

    <s:FormItem label="State" > 
        <MyComp:StateComboBox/>
    </s:FormItem>
</s:Form>

The following application file references the AddressForm component in the <AddressForm> tag:

<?xml version="1.0"?>
<!-- createcomps_mxml/MyApplicationAddressForm.mxml-->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:s="library://ns.adobe.com/flex/spark" 
    xmlns:mx="library://ns.adobe.com/flex/mx"  
    xmlns:MyComp="*" >

    <MyComp:AddressForm/> 

</s:Application>

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

If you include child tags of the root container tag in an MXML component file, you cannot add child tags when you use the component as a custom tag in another MXML file. If you define an empty container in an MXML file, you can add child tags when you use the component as a custom tag.

Note: The restriction on child tags refers to the child tags that correspond to visual components. Visual components are subclasses of the UIComponent component. You can always insert tags for nonvisual components, such as ActionScript blocks, styles, effects, formatters, validators, and other types of nonvisual components, regardless of how you define your custom component.

The following example defines an empty Form container in an MXML component:

<?xml version="1.0"?>
<!-- createcomps_mxml/EmptyForm.mxml -->
<s:Form xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:s="library://ns.adobe.com/flex/spark" 
    xmlns:mx="library://ns.adobe.com/flex/mx"
/>

This component defines no children of the Form container; therefore, you can add children when you use it in another MXML file, as the following example shows:

<?xml version="1.0"?>
<!-- mxml/MainEmptyForm.mxml-->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:s="library://ns.adobe.com/flex/spark" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:MyComp="*">

    <MyComp:EmptyForm>    
        <s:FormItem label="Name">
            <s:TextInput/>
        </s:FormItem>
    </MyComp:EmptyForm>
</s:Application>

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

The AddressForm.mxml file specifies the Form container as its root tag. Because you define a container as the root tag of the MXML component, you are creating a subclass of that container, and you can reference all of the properties and methods of the root tag when using your MXML component. Therefore, in the main application, you can reference all of the properties of the Form container in the MXML tag that corresponds to your custom component, or in any ActionScript code in the main application. However, you cannot reference properties of the children of the Form container.

For example, the following example sets the fontSize property and a listener for the creationComplete event for your custom control, but you cannot specify properties for the child CheckBox or TextInput controls of the Form container:

<?xml version="1.0"?>
<!-- createcomps_mxml/MainEmptyFormProps.mxml-->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:s="library://ns.adobe.com/flex/spark" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:MyComp="*">

    <fx:Script>
        <![CDATA[
            import mx.events.FlexEvent;

            private function handleCreationCompleteEvent(event:FlexEvent):void {
                // Handle creationComplete event.
            }   
        ]]>
    </fx:Script>

    <MyComp:AddressForm fontSize="15" 
        creationComplete="handleCreationCompleteEvent(event);"/>
</s:Application>

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

To configure the children of a custom MXML component, you define new properties in the MXML component, and then use those new properties to pass configuration information to the component children. For more information, see Advanced MXML components.