DataBinding under the hood (part 2): Features

Published by Manfred Karrer on Monday, 20 of April , 2009 at 21:31

There are many different ways how to use DataBinding.
Beyond the obvious ones there are a few more which could be a nice feature for some weird hacks…

Flex gives us 4 different techniques to use DataBinding:

  • Curly Brackets in MXML
  • Binding tag
  • BindingUtils
  • ChangeWatcher

Lets have an overview of the possibilities of each technique:

Curly Brackets in MXML

The most obvious one: Binding a source value to a destination value:

This works also for readOnly properties and static constants. You can omit the Bindable metadata tag because the Binding is only triggered at application startup. Static variables are not supported (the Adobe docs are not correct at this). Also Binding to style properties are not supported.

To add 2 way Binding simply use the curly brackets syntax in both objects crosswise:

[code lang="actionscript3"]


Here some code examples for Actionscript and E4X expressions:

[code lang="actionscript3"]
// Method calls and calculations

// Perform string concatenation

// Perform a conditional operation using a ternary operator

// E4X expressions


A nice feature which is probably not typically used in your daily work, is the possibility to bind to functions. You can use a function as source for your Binding:
To make this work you have to mark the function with the Bindable metadata tag and define your custom event name. When you dispatch an Event with your selected event name the Binding is triggered and the destination gets the return value of your function.

[code lang="actionscript3"]



As we have seen in the previous post Binding in MXML is not the fastest solution.
Your better choice for writing high performacne applications is BindingUtils:
You have 2 static methods: BindingUtils.bindProperty and BindingUtils.bindSetter

[code lang="actionscript3"]



The name of the arguments in the API are a little bit confusing (at least for me).

[code lang="actionscript3"]
public static function bindProperty(site:Object, prop:String,
            host:Object, chain:Object,
            commitOnly:Boolean = false):ChangeWatcher

The first 2 parameters are the destination object and property name, and the last 2 the source object and property name.

  • site:Object -> destination object
  • prop:String -> destination property name
  • host:Object -> source object
  • chain:Object -> source property name(s)

Binding supports changes on every bindable element in the source chain. If one element is changing the Binding is triggered.
You can specify the chain as a single String for the name of your property (if there is only one chain element) or as Array of property name Strings for each bindable chain element.

[code lang="actionscript3"]
// bind to object: user.setting.volume
BindingUtils.bindProperty(myText0, "text", user, ["setting", "volume"]);

But there is another possibility to set the chain argument:
You can pass an Object in the form:

[code lang="actionscript3"]
{ name: propertyName,
  getter: function(host) { return host[propertyName] }

This Object must contain the name of the property and a function returning a value, which is normally a getter function for a public bindable property of the source object.
This feature opens interesting possibilities.
The function is basically a wrapper which returns the value of the source. I am not sure at the moment where to use this, but it´s good to know that there is an open door…

When using chains with BindingUtils you can choose if the chain elements in-between are bindable.
If an element in-between is not bindable, no Binding is triggered if this element changes.
This is not the case when you use the chains in MXML. You got a compiler warning and a runtime exception if one of the in-between elements are not marked as bindable.

Here is a code example for using chains:

[code lang="actionscript3"]

public class User
    public var setting:Setting;
    public function User(setting:Setting)
        this.setting = setting;

public class Setting
    public var title:String = "blabla";
    public function Setting()
        setInterval(function():void {
                     title = int(Math.random()*10000).toString()
                     }, 100);

The ChangeWatcher is the class used inside of BindingUtils. ChangeWatcher implements the event handling and the handling for the chains. BindingUtils are just a more convenience way and adds nearly no overhead compared to use ChangeWatcher directly.

Here are some additional snippets about DataBinding:
You can use multiple [Bindable] tags. Doing this lets you trigger Binding from different events.

When you use Binding in MXML the addEventListener method uses a weak reference.
This is important due the fact that you cannot unbind with the curly brackets syntax. Without weak reference Binding in MXML would be a potential memory leak.

When using BindingUtils you are responsible for calling the unwatch() method on your ChangeWatcher object (a ChangeWatcher object is the return value of BindingUtils.bindProperty). The addEventListener method in the ChangeWatcher is not using weak references, so if you don´t do your housekeeping carefully, this could lead to a memory leak.

In UIComponent there is the method executeBindings() which force a trigger to all Bindings on this component. This could help sometimes when a Binding is not firing by it´self correctly, but of course should be taken carefully because it´s probably just healing a symptom not the underlying problem.

When you use the [Bindable] metadata tag before a class definition, it only applies to public properties; it does not apply to private or protected properties, or to properties defined in any other namespace. You must insert the [Bindable] metadata tag before a nonpublic property to make it usable as the source for a data binding expression.

The DataBinding reference can be found at Adobe LiveDocs.

Comments Off on DataBinding under the hood (part 2): Features

Category: Actionscript,Flash,Flex

No Comments

No comments yet.

Sorry, the comment form is closed at this time.