Search code examples
apache-flexdata-bindingactionscriptairmxml

Bind to object property


AS

[Bindable]
var object:Object = {
    property: "Property"
};

MXML

<s:Label text="{object.property}"/>

The labels text will be "Property", but if object.property is changed, the label isn't updated. Is there any way around this?


Solution

  • Properties of an object or collection will not dispatch a property change event unless implemented.

    Likewise to your example, a change to an Array element will not be bound.

    Collections such as ArrayCollection wrap objects within a proxy to dispatch events for binding.

    Use an ObjectProxy to dispatch changes to your object.

    Instantiate an ObjectProxy and listen for PropertyChangeEvent:

    objectProxy = new ObjectProxy(object);
    objectProxy.addEventListener(PropertyChangeEvent.PROPERTY_CHANGE, propertyChangeHandler);
    

    Access your object via the proxy, such as setting a property named 'property':

    objectProxy.property = "Hello, world";
    

    This example creates an ObjectProxy with a timer to change the 'property' member every second:

    <?xml version="1.0" encoding="utf-8"?>
    <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
                   xmlns:s="library://ns.adobe.com/flex/spark"
                   xmlns:mx="library://ns.adobe.com/flex/mx"
                   minWidth="955"
                   minHeight="600"
                   creationComplete="creationCompleteHandler(event)">
    
    
        <fx:Script>
            <![CDATA[
                import mx.events.FlexEvent;
                import mx.events.PropertyChangeEvent;
                import mx.utils.ObjectProxy;
    
    
                private var object:Object = {};
                private var objectProxy:ObjectProxy;
    
                private var timer:Timer;
    
                protected function creationCompleteHandler(event:FlexEvent):void
                {
                    objectProxy = new ObjectProxy(object);
                    objectProxy.addEventListener(PropertyChangeEvent.PROPERTY_CHANGE, propertyChangeHandler);
    
                    timer = new Timer(1000);
                    timer.addEventListener(TimerEvent.TIMER, timerHandler);
                    timer.start();
                }
    
                protected function propertyChangeHandler(event:PropertyChangeEvent):void
                {
                    label.text = (event.source).property;
                }
    
                protected function timerHandler(event:TimerEvent):void
                {
                    objectProxy.property = Math.random() * 1000;
                }
            ]]>
        </fx:Script>
    
    
        <s:Label id="label" />
    
    
    </s:Application>