Binding in flex 3 magic in curly brackets

A lot of things have been said about binding (read basics). But to really understad what is going on behind the scenes lets do some experiments… First to mention is, the curly brackets magic does not work as BindingUtils does. BindingUtils lets you bind only one setter, but curly brackets lets you bind whole logic.

  • test1 – notice constant C1 in (binding constants is valid, and is working without Binding meta tag) and some plus inside expression “Working: {C1 + ‘ ‘ + v2}”
  • test2 – you can use more curly brackets expressions within one attribute “Working: {C1} {v2.toUpperCase()}”
  • test3 – even if you expect function result from your bindable variable it will work “Working: {C1} {uberFunc(v2)}”
  • test4 – notice some math functions here “Working: {v3 + v3}, {Math.pow(v3, 2)}”
  • test5 – simple Object and Array is not working (nor ArrayCollection using brackets) “Not working: {v4.v}, {v5[0]}, {v6[0]}”
  • test6 – getItemAt() on ArrayCollection works just smooth “Working: {v6.getItemAt(0)}”
  • test7 – once you use curly brackets you can not remove binding, but binding can be unbinded when binded by BindingUtils. (both getter and setter in bindProperty must be public!)
  • test8 – binding works when correct event is dispatched “{foo.gimmeSometing()}”
  • test9 – binding with ternary operator is super powerful “{v2 == ‘world’ ? ‘is world’ : ‘not world’}”

Take a look at the test application:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical"
    applicationComplete="init()">
<mx:Script>
<![CDATA[
    import mx.binding.utils.ChangeWatcher;
    import mx.binding.utils.BindingUtils;
    import mx.collections.ArrayCollection;
    
    private static const C1:String = "Hallo";
    
    [Bindable]
    private var v1:String = "hallo";
    
    [Bindable]
    public var v2:String = "world";
    
    [Bindable]
    private var v3:Number = 1;
    
    [Bindable]
    private var v4:Object = {v:1};
    
    [Bindable]
    private var v5:Array = [1];
    
    [Bindable]
    private var v6:ArrayCollection = new ArrayCollection([1]);
    
    [Bindable]
    private var foo:Foo = new Foo();
    
    private var changeWatcher:ChangeWatcher;
    
    private function uberFunc(value:String):String
    {
        return "(" + value + ")";
    }
    
    private function clickHandler():void
    {
        v2 = v2 == "world" ? "dolly" : "world";
        v3 *= 2;
        v4.v += 1;
        v5[0] += 1;
        v6[0] += 1;
        foo.somevar = v2;
    }
    
    private function init():void
    {
        // easy to remember parameters test7.text = this.v2 (notice order)
        changeWatcher = BindingUtils.bindProperty(test7, "text", this, "v2");
    }
    
    private function unbindHandler():void
    {
        if(changeWatcher)
        {
            changeWatcher.unwatch();
            changeWatcher = null;
        }
        test6.text = "removed? (not really, try click change)";
        test7.text = "removed";
    }
]]>
</mx:Script>
<mx:Text id="test1" text="Working: {C1 + ' ' + v2}" />
<mx:Text id="test2" text="Working: {C1} {v2.toUpperCase()}" />
<mx:Text id="test3" text="Working: {C1} {uberFunc(v2)}" />
<mx:Text id="test4" text="Working: {v3 + v3}, {Math.pow(v3, 2)}" />
<mx:Text id="test5" text="Not working: {v4.v}, {v5[0]}, {v6[0]}" />
<mx:Text id="test6" text="Working: {v6.getItemAt(0)}" />
<mx:Text id="test7" text="Removable: "/>
<mx:Text id="test8" text="{foo.gimmeSometing()}"/>
<mx:Text id="test9" text="{v2 == 'world' ? 'is world' : 'not world'}"/>
<mx:Button label="change" click="clickHandler()" />
<mx:Button label="unbind" click="unbindHandler()" />
</mx:Application>

Click change to see how values really changes. Click unbind button to see how unbinding on test7 works and on test6 not (click on change button again after unbind).

Foo.as class

package
{
    import flash.events.Event;
    import flash.events.EventDispatcher;
    import flash.events.IEventDispatcher;

    public class Foo extends EventDispatcher
    {
        private var _somevar:String = "hello";
        
        public function Foo(target:IEventDispatcher=null)
        {
            super(target);
        }
        
        public function set somevar(value:String):void
        {
            _somevar = value;
            dispatchEvent(new Event("somevarChanged"));
        }
        
        [Bindable(event="somevarChanged")]
        public function gimmeSometing():String
        {
            return _somevar;
        }
    }
}

Leave a comment

Please be polite and on topic. Your e-mail will never be published.