About data binding

Data binding is the process of tying the data in one object to another object. It provides a convenient way to pass data between the different layers of the application. Data binding requires a source property, a destination property, and a triggering event that indicates when to copy the data from the source to the destination. An object dispatches the triggering event when the source property changes.

Adobe Flex provides three ways to specify data binding: the curly braces ({}) syntax in MXML, the <fx:Binding> tag in MXML, and the BindingUtils methods in ActionScript. The following example uses the curly braces ({}) syntax to show a Label control that gets its data from a TextInput control’s text property:

<?xml version="1.0"?>
<!-- binding/BasicBinding.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">
    <s:layout>
        <s:VerticalLayout/>
    </s:layout>

    <s:TextInput id="myTI" text="Enter text here"/>
    <s:Label id="myText" text="{myTI.text}"/>
</s:Application>

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

The property name inside the curly braces is the source property of the binding expression. When the value of the source property changes, Flex copies the current value of the source property, myTI.text, to the destination property, the Label control’s text property.

You can include ActionScript code and E4X expressions as part of the data binding expressions, as the following example shows:

<?xml version="1.0"?>
<!-- binding/BasicBindingWithAS.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">
    <s:layout>
        <s:VerticalLayout/>
    </s:layout>

    <s:TextInput id="myTI"/>
    <s:Label id="myText" text="{myTI.text.toUpperCase()}"/>
</s:Application>

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

In this example, you use the ActionScript method String.toUpperCase() to convert the text in the source property to upper case when Flex copies it to the destination property. For more information, see Using ActionScript in data binding expressions and Using an E4X expression in a data binding expression.

You can use the <fx:Binding> tag as an alternative to the curly braces syntax. When you use the <fx:Binding> tag, you provide a source property in the <fx:Binding> tag’s source property and a destination property in its destination property. The following example uses the <fx:Binding> tag to define a data binding from a TextInput control to a Label control:

<?xml version="1.0"?>
<!-- binding/BasicBindingMXML.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">
    <s:layout>
        <s:VerticalLayout/>
    </s:layout>
    
    <fx:Binding source="myTI.text" destination="myText.text"/>

    <s:TextInput id="myTI"/>
    <s:Label id="myText"/>   
</s:Application>

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

In contrast to the curly braces syntax, you can use the <fx:Binding> tag to completely separate the view (user interface) from the model. The <fx:Binding> tag also lets you bind multiple source properties to the same destination property because you can specify multiple <fx:Binding> tags with the same destination. For an example, see Binding more than one source property to a destination property.

The curly braces syntax and the <fx:Binding> tag both define a data binding at compile time. You can also use ActionScript code to define a data binding at run time, as the following example shows:

<?xml version="1.0"?>
<!-- binding/BasicBindingAS.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">
    <s:layout>
        <s:VerticalLayout/>
    </s:layout>

    <fx:Script>
      <![CDATA[
        import mx.binding.utils.*;

        // Define data binding.
        public function initBindingHandler():void {
            BindingUtils.bindProperty(myText, "text", myTI, "text");
        }
      ]]>    
    </fx:Script>

    <s:TextInput id="myTI"/>
    <s:Label id="myText" preinitialize="initBindingHandler();"/>
</s:Application>

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

In this example, you use the static BindingUtils.bindProperty() method to define the binding. You can also use the BindingUtils.bindSetter() method to define a binding to a function. For more information, see Defining data bindings in ActionScript.

Notice in this example that you use the preinitialize event to define the data binding. This is necessary because Flex triggers all data bindings at application startup when the source object dispatches the initialize event. For more information, see When data binding occurs.

When data binding occurs

Binding occurs under the following circumstances:

  1. The binding source dispatches an event because the source has been modified.

    This event can occur at any time during application execution. The event triggers Flex to copy the value of the source property to the destination property.

  2. At application startup when the source object dispatches the initialize event.

    All data bindings are triggered once at application startup to initialize the destination property.

To monitor data binding, you can define a binding watcher that triggers an event handler when a data binding occurs. For more information, see Defining binding watchers.

The executeBindings() method of the UIComponent class executes all the bindings for which a UIComponent object is the destination. All containers and controls, as well as the Repeater component, extend the UIComponent class. The executeChildBindings() method of the Container and Repeater classes executes all of the bindings for which the child UIComponent components of a Container or Repeater class are destinations. All containers extend the Container class.

These methods give you a way to execute bindings that do not occur as expected. By adding one line of code, such as a call to the executeChildBindings() method, you can update the user interface after making a change that does not cause bindings to execute. However, you should only use the executeBindings() method when you are sure that bindings do not execute automatically.

Properties that support data binding

You can use all properties of an object as the destination of a data binding expression. However, to use a property as the source of a data binding expression, the source object must be implemented to support data binding, which means that the object dispatches an event when the value of the property changes to trigger the binding. In this topic, a property that can be used as the source of a data-binding expression is referred to as a bindable property.

In the ActionScript 3.0 Reference for the Adobe Flash Platform, a property that can be used as the source of a data binding expression includes the following statement in its description:

“This property can be used as the source for data binding.”

Using read-only properties as the source for data binding

You can use a read-only property defined by a getter method, which means no setter method, as the source for a data-binding expression. Flex performs the data binding once when the application starts.

Using static properties as the source for data binding

You can automatically use a static constant as the source for a data-binding expression. Flex performs the data binding once when the application starts.

You can use a static variable as the source for a data-binding expression. Flex performs the data binding once when the application starts.

Creating properties to use as the source for data binding

When you create a property that you want to use as the source of a data binding expression, Flex can automatically copy the value of the source property to any destination property when the source property changes. To signal to Flex to perform the copy, you must use the [Bindable] data tag to register the property with Flex.

The [Bindable] metadata tag has the following syntax:

[Bindable] 
[Bindable(event="eventname")]

You can optionally omit the event keyword, and specify the tag as shown below:

[Bindable("eventname")]

If you omit the event name, Flex automatically creates an event named propertyChange, and Flex dispatches that event when the property changes to trigger any data bindings that use the property as a data-binding source. If you specify the event name, it is your responsibility to dispatch the event when the source property changes. For more information and examples of using the [Bindable] metadata tag, see Using the Bindable metadata tag.

The following example makes the maxFontSize and minFontSize properties that you defined as variables usable as the sources for data bindings expressions:

<?xml version="1.0"?>
<!-- binding/FontPropertyBinding.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">
    <s:layout>
        <s:VerticalLayout/>
    </s:layout>
    
    <fx:Script>
        <![CDATA[
            // Define public vars for tracking font size.
            [Bindable]
            public var maxFontSize:Number = 15;

            [Bindable]
            public var minFontSize:Number = 5;
        ]]>    
    </fx:Script>
    
    <s:Label text="{maxFontSize}"/>
    <s:Label text="{minFontSize}"/>

    <s:Button click="maxFontSize=20; minFontSize=10;"/>
</s:Application>

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

When you click the Button control, you update the values of the maxFontSize and minFontSize properties, and trigger a data binding update to the Label controls.

Note: If you omit the [Bindable] metadata tag, the compiler issues a warning stating that the data binding mechanism cannot detect changes to the property. For more information, see Using the Bindable metadata tag.

Data binding uses

Common uses of data binding include the following:

  • To bind properties of user interface controls to other user interface controls.

  • To bind properties of user interface controls to a middle-tier data model, and to bind that data model’s fields bound to a data service request (a three-tier system).

  • To bind properties of user interface controls to data service requests.

  • To bind data service results to properties of user interface controls.

  • To bind data service results to a middle-tier data model, and to bind that data model’s fields to user interface controls. For more information about data models, see Storing data.

  • To bind an ArrayCollection or XMLListCollection object to the dataProvider property of a List-based control.

  • To bind individual parts of complex properties to properties of user interface controls. An example would be a master-detail scenario in which clicking an item in a List control displays data in several other controls.

  • To bind XML data to user interface controls by using ECMAScript for XML (E4X) expressions in binding expressions.

Although binding is a powerful mechanism, it is not appropriate for all situations. For example, for a complex user interface in which individual pieces must be updated based on strict timing, it would be preferable to use a method that assigns properties in order. Also, binding executes every time a property changes, so it is not the best solution when you want changes to be noticed only some of the time.