Can I bind a Flex component property to a function?

14,663

Solution 1

According to the Flex docs, as long as the property is bindable, you can simply do this (I've included the two extra buttons to demonstrate):

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">

    <mx:Script>
        <![CDATA[

            [Bindable]
            private var currentUser:String = "Bill";

            private function isUserAllowed(user:String):Boolean
            {
                if (user == "Bill")
                {
                    return true;
                }

                return false;
            }

        ]]>
    </mx:Script>

    <mx:VBox>
        <mx:Button label="My Button" enabled="{isUserAllowed(currentUser)}" />
        <mx:HBox>
            <mx:Button label="Try Tom" click="{currentUser = 'Tom'}" />
            <mx:Button label="Try Bill" click="{currentUser = 'Bill'}" />
        </mx:HBox>
    </mx:VBox>

</mx:Application>

Without currentUser marked [Bindable], though, it won't work.

Another way to go, if you wanted to bind more literally to the function (this is also expressed in the docs), would be to have the function respond to an event you dispatch when the current user changes, like so:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" initialize="init()">

    <mx:Script>
        <![CDATA[

            private var _currentUser:String = "Bill";

            public function set currentUser(value:String):void
            {
                if (_currentUser != value)
                {
                    _currentUser = value;
                    dispatchEvent(new Event("userChanged"));
                }
            }           

            [Bindable(event="userChanged")]
            private function isUserEnabled():Boolean
            {
                if (_currentUser == "Bill")
                {
                    return true;
                }

                return false;
            }

        ]]>
    </mx:Script>

    <mx:VBox>
        <mx:Button label="My Button" enabled="{isUserEnabled()}" />
        <mx:HBox>
            <mx:Button label="Try Tom" click="{currentUser = 'Tom'}" />
            <mx:Button label="Try Bill" click="{currentUser = 'Bill'}" />
        </mx:HBox>
    </mx:VBox>

</mx:Application>

So there are a couple of ways. IMO, the second seems somehow more proper, but there's definitely nothing wrong with the first. Good luck!

Solution 2

Here's what I've done a few times in similar circumstances:

<mx:Script>
<![CDATA[

    [Bindable] var _username : String;

    private function isUserAllowed (userName:Boolean):Boolean {
        if (userName == 'Tom')
            return true;
        if (userName == 'Bill')
            return false;
    }

]]>
</mx:Script>

<mx:Button label="Create PO"
    id="createPOButton"
    enabled="{isUserAllowed(_username)}"
    click="createPOButton_Click()" />

This way, when the Bindable _username changes, it will fire a change notification. Since the label is listening to _username changes (even if it is simply a parameter to another function), the enabled property will be re-evaluated.

Share:
14,663
SkunkSpinner
Author by

SkunkSpinner

I love development.

Updated on June 21, 2022

Comments

  • SkunkSpinner
    SkunkSpinner about 2 years

    I want to set the enabled property on a button based on the return value of a function that has one or more parameters. How can I do this?

    private function isUserAllowed (userName:Boolean):Boolean {
       if (userName == 'Tom')
          return true;
       if (userName == 'Bill')
          return false;
    }
    
    <mx:Button label="Create PO" id="createPOButton"
    enabled="<I want to call isUserAllowed ('Bill') or isUserAllowed ('Tom') here>"
    click="createPOButton_Click()" />
    
  • SkunkSpinner
    SkunkSpinner over 15 years
    But where do I pass in the parameter to the function isUserAllowed? I want to call the function dynamically when it tries to set the enabled property.
  • ForYourOwnGood
    ForYourOwnGood over 15 years
    The variable is going to be a global variable, there is no need to pass it to the function.
  • Edyn
    Edyn over 11 years
    +1 Option 2 all the way! Though not a direct answer to the question, a much better approach.