Data binding in Flex

by Peter deHaan on October 1, 2007

in Binding, BindingUtils, Data Binding

The following examples show a few different ways to bind data in Flex.

Full code after the jump.

The following example shows how you can use the <mx:Binding /> tag to bind values between two controls:

View MXML

<?xml version="1.0" encoding="utf-8"?>
<!-- http://blog.flexexamples.com/2007/10/01/data-binding-in-flex/ -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
        layout="vertical"
        verticalAlign="middle"
        backgroundColor="white">

    <mx:Binding source="textInputSrc.text"
            destination="textInputDst.text" />

    <mx:Form>
        <mx:FormItem label="source:">
            <mx:TextInput id="textInputSrc" />
        </mx:FormItem>
        <mx:FormItem label="destination:">
            <mx:TextInput id="textInputDst"
                    width="{textInputSrc.width}" />
        </mx:FormItem>
    </mx:Form>

</mx:Application>

View source is enabled in the following example.

The following example shows how you can use the static BindingUtils.bindProperty() method to bind values between two controls:

View MXML

<?xml version="1.0" encoding="utf-8"?>
<!-- http://blog.flexexamples.com/2007/10/01/data-binding-in-flex/ -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
        layout="vertical"
        verticalAlign="middle"
        backgroundColor="white"
        creationComplete="init();">

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

            private function init():void {
                BindingUtils.bindProperty(textInputDst, "text", textInputSrc, "text");
            }
        ]]>
    </mx:Script>

    <mx:Form>
        <mx:FormItem label="source:">
            <mx:TextInput id="textInputSrc" />
        </mx:FormItem>
        <mx:FormItem label="destination:">
            <mx:TextInput id="textInputDst"
                    width="{textInputSrc.width}" />
        </mx:FormItem>
    </mx:Form>

</mx:Application>

View source is enabled in the following example.

The following example shows how you can use the static BindingUtils.bindSetter() method to call a method whenever the source property is changed:

View MXML

<?xml version="1.0" encoding="utf-8"?>
<!-- http://blog.flexexamples.com/2007/10/01/data-binding-in-flex/ -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
        layout="vertical"
        verticalAlign="middle"
        backgroundColor="white"
        creationComplete="init();">

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

            private function init():void {
                BindingUtils.bindSetter(setterFunc, textInputSrc, "text");
            }

            private function setterFunc(str:String):void {
                textInputDst.text = str;
            }
        ]]>
    </mx:Script>

    <mx:Form>
        <mx:FormItem label="source:">
            <mx:TextInput id="textInputSrc" />
        </mx:FormItem>
        <mx:FormItem label="destination:">
            <mx:TextInput id="textInputDst"
                    width="{textInputSrc.width}" />
        </mx:FormItem>
    </mx:Form>

</mx:Application>

View source is enabled in the following example.

{ 16 comments… read them below or add one }

1 Clint October 10, 2007 at 11:19 am

Hmm, nice. But why would I use anything but [Bindable]? Can you include reasons, explainations, or circumstances where one might want to use these alternatives instead? Pros and cons or something…

Reply

2 Ryan November 6, 2007 at 3:46 pm

One scenario where you might use the BindingUtils is when you generate UI components at runtime based on the results of a dataservice. This can be handy for performing binding on non-data aware display components such as Grid, where the the state maintenance is largely up to the developer and what child components the grid contains.

Reply

3 Simon February 13, 2008 at 7:28 am

I had the situation when using the Cairngorm framework that I needed to update a mx:progressbar component using the setProgress function whenever a variable in the ModelLocator changed. I used the BindingUtils.bindSetter to call the function whenever the variable changed, just to give you another example.

Reply

4 guillaume.jt April 1, 2008 at 2:27 am

Well done :)

Reply

5 Derek Basch April 24, 2008 at 4:19 pm

A few examples of how to use the binding utilities with Objects and ArrayCollections would be most appreciated :).

Reply

6 peterd May 31, 2008 at 12:53 pm

Added SWFs.

Peter

Reply

7 Alex July 25, 2008 at 12:15 pm

Hi,

Is it possible to bind to a function that requires a parameter ?

ex :

[Bindable("change")]
public function getString(obj:Object):String
{

}

Thanks

Reply

8 Anonymous February 17, 2009 at 3:45 am

thanks for the code, but the text in the destination loses its property like font size, font type, font color on pressing a space bar, how to avoid that

Reply

9 simon April 7, 2009 at 6:03 pm

A few examples of how to use the binding utilities with Objects and ArrayCollections would be most appreciated too.

Reply

10 Webdevotion April 19, 2009 at 11:15 pm

Another way could be to use Actionscript only as described in a blogpost of mine. It shows you how you can bind to a component and use a labelFunction to return a value, instead of the actual value (e.g.: a formatted datestring instead of a date object).

http://webdevotion.be/blog/2009/04/20/binding-between-a-datefield-and-a-button-label-at-runtime/

Reply

11 xueyu July 24, 2009 at 4:59 am

very nice example, thank you very much!

Reply

12 Alograg July 27, 2009 at 3:59 pm

This post not render on Chrome.

Reply

13 Peter deHaan July 28, 2009 at 6:42 am

Works for me on Vista 64 w/ Google Chrome 2.0.172.33.

Reply

14 Anne September 14, 2009 at 1:06 pm

Peter,

Thanks for the site – I refer to it frequently. On to the matter at hand:

I am attempting to bind an object’s property to another object’s property for writing to a mySQL database. It works correctly, however, I need to do this task a dynamic number of times based on user interaction with the datagrid (based on how many items they have selected in the “multipleSelectionsAllowed” datagrid).

code is something like:

for each (var obj:Object in myObjCollection) //myObjCollection is the list of selected items in datagrid
{
BindingUtils.bindProperty(_destObj, "myProp", obj, "myProp");
var asyncToken:AsyncToken = _destObj.save();
}

where destObj is defined as the same type object as obj

The line “var asyncToken:AsyncToken = _destObj.save();” works fine outside of the loop with a separate binding of source/dest in but only does this for one item, not each in the list.

Any help is much appreciated :D

Reply

15 Anne September 14, 2009 at 1:08 pm

By the way, the error I am getting is something like “Record is locked and can’t be saved” – this only occurs in the for loop, not in the single call (which works/updates correctly)

Reply

16 Marc de Kwant January 20, 2010 at 1:07 am

Since bi-directional binding is not supported in Flex 3, you can use a mapping file and a binder class using the mapping file to support bi-directional binding.
Furthermore this will reduce code and extract the mapping/binding concern from your main application code.
Sample: Flex binding

Kind regards,

Marc

Reply

Leave a Comment

Sorry, this blog is terrible at eating HTML comments.
If you're pasting any HTML/XML/MXML code, you need to convert your < characters to &lt; and your > characters to &gt; .

You can use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="">

Anti-Spam Protection by WP-SpamFree

Previous post:

Next post: