actionscript-3flashapache-flexadobebindable

Binding in Flex: How to make a variable automatically update when another variable is changed?


I know that it is possible to make a parameter of a component depend on a variable, provided that variable contains the [Bindable] tag. This means that updating the value of the Bindable variable automatically updates the component.

Is it possible to make another variable depend on a Bindable variable?

In the example below I have a variable btnClicked that is bound. When btnClicked is changed by the function btnClick() being called, the text in the TextArea is updated as expected.

I would like to be able to make another variable, btnText, be updated when btnClicked is updated. I do not know how to communicate this dependency. In the code below the value of btnText is initially "clickMe" as expected. However, when btnClicked changes, the text on the button does not update to "unclickMe".

<fx:Script>
    <![CDATA[
        [Bindable]
        public var btnClicked:Boolean = false;

        public function btnClick():void{
            btnClicked = !btnClicked;
        }

        [Bindable]
        public function get btnText():String{
            return btnClicked?"unclickMe":"clickMe";
        }
    ]]>
</fx:Script>

<s:Button click="btnClick()" label="{btnText}"/>

<s:TextArea y="50" text="{btnClicked?'Button is clicked':'Button is unclicked'}"/>

How can I change the code above so that btnText automatically updates when btnClicked is changed?

Would it be possible to have an arbitrarily long chain of connected variables each of which updates when the previous one updates?


Solution

  • You can also use a ChangeWatcher to detect when your bindable property is updated :

    <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" creationComplete="init(event)">
    
        <fx:Script>
            <![CDATA[
    
                import mx.binding.utils.ChangeWatcher;
                import mx.events.FlexEvent;
    
                public var watcher:ChangeWatcher;
    
                [Bindable]
                public var btnClicked:Boolean = false;
                [Bindable]
                public var btnText:String = 'clickMe';
    
                protected function btnClick():void {
                    btnClicked = !btnClicked;
                }
    
                protected function init(event:FlexEvent):void
                {
                    watcher = ChangeWatcher.watch(this, 'btnClicked', watcherListener);
                }
    
                protected function watcherListener(event:Event):void {
                    btnText = btnClicked ? 'unclickMe' : 'clickMe';
                }
    
            ]]>
        </fx:Script>
    
        <s:Button x="303" y="30" label="{btnText}" click="btnClick()"/> 
        <s:TextArea x="303" id="txt" y="96" text="{btnClicked ? 'Button is clicked' : 'Button is unclicked'}"/>
    
    </s:Application>
    

    Hope that can help.