Flex 4 bidirectional data binding: chicken or egg?

One of the many new features in Flex 4 is bidirectional data binding. I think it’s a useful addition because many times you have a data model that you bind to a form, and you want any changes in the form to be reflected back into the data model. With bidirectional data binding you can do this on the same line that you defined the binding, so there is no need of additional code (as was the case in Flex 3).

Here are the two syntaxes for declaring the binding as bidirectional:

  • <s:TextInput id=”txt” text=”@{value}”/> – notice the addition of “@”, this is the operator used to mark the binding as bidirectional
  • <fx:Binding destination=”txt.text” source=”value” twoWay=”true”/> – notice the twoWay attribute

However, I have to warn you that it might not work as you’d expect. Let’s have a look at the following code:

   1: <?xml version="1.0" encoding="utf-8"?>
   2: <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark"
   3:     xmlns:mx="library://ns.adobe.com/flex/halo" minWidth="1024" minHeight="768" creationComplete="init()">
   4:     <fx:Script>
   5:         <![CDATA[
   6:
   7:             [Bindable]
   8:             private var labelValue:String = "Hello World!";
   9:
  10:             private function init():void {
  11:                 trace(labelValue);
  12:                 trace(txt.text);
  13:             }
  14:
  15:         ]]>
  16:     </fx:Script>
  17:     <s:TextInput id="txt" text="@{labelValue}"/>
  18: </s:Application>

We have a String variable with the default value “Hello World!”, and this variable is the source of data binding for the TextInput text variable. You might think that the execution of init() function will output:

   1: Hello World!
   2: Hello World!

Actually, the output is nothing! When I run this code for the first time I was puzzled. I then used the debugger to see what it was happening behind the curtains.

This is what I found:

  1. The application starts to initialize
  2. First the labelValue variable is initialized and triggers the property watcher (because it is used in binding)
  3. But at this point, the TextInput field is null, and the binding cannot be completed
  4. Next, the initialization of TextInput starts
  5. By default, the text property of this field is an empty string “”
  6. Because the TextInput is part of data binding too (remember the data binding is bidirectional in my code), the property watcher executes and sets the value of labelValue to empty string
  7. Finally, the application finishes its creation and the init() function is executed. By now, both the variable and the text property of the TextInput have the same value, empty string

Elementary my dear Watson!

If I want the code to work as I intended, I have to initialize the labelValue variable on the creationComplete event or after:

   1: private function init():void {
   2:     labelValue = "Hello Wold!";
   3: }

I guess this is one of those problems: who was first, the chicken or the egg?

2 thoughts on “Flex 4 bidirectional data binding: chicken or egg?

  1. It is possible to experiment the same thing Flex 3 bindings (manual bidirectional declaration).

    It’s important to ensure that your components are initialized before data is binded (with whatever binding strategy/mecanism/version).

    You must be aware of this in the case you “bypass” the Flex components lifecyle).

  2. Thank you for that advice.
    I experienced the same problem but before I wanted to dive into the deep waters of Flex I did some research on the net.

Leave a Reply

Your email address will not be published. Required fields are marked *