Flex Tips - Using Bindable Metadata Events
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 |
2. Declare an instance of the class preceded with the [Bindable] metadata tag
[Bindable] |
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");
// Value object class marked bindable |
<!-- Application file --> |
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 |
[Bindable(event="propertyChange")] |
public class Order |
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.
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 Waters
To 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 |
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.
- Broadcast an event when a bindable property value changes
- 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:
- 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. - 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. 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 |
<?xml version="1.0" encoding="utf-8"?> |
Labels: Data Binding, Flex Tips, Jeremy Mitchell

