1st; when i use function biding (<textInput text="{myInstance.toString()}"/>) , function binding works fine


are you sure about that? I could be wrong, but I would guess that if you add a button under the TextInput tag your TextInput text value will not update as expected on the button click.

<mx:Button label="Test" click="myInstance.someProperty = 'testing';" />

(If in fact it does update for you, I would love to see your example code since it's possible there is an aspect of binding that I am missing.)

HOWEVER, the problem you are having with the item renderer is somewhat related, but different, problem. Item renderers use 'data' as generic object to hold the data passed to the item render. That object itself is bindable AND if the entire data object changes the functions and properties will update. However, changes to the underlying properties or functions will not be detected without setting up binding a little more explicitly. (Usually you don't get compiler warnings, but it you run in debug mode you should get run time messages in the console) My solution to this is to explicitly bind the data property to an internal property of the item renderer using MXML. When I do this the binding works correctly.

In my item renderer...

        <mx:Script>
                <![CDATA[
                        [Bindable]
                        private var myInternalData:MyCustomClass;               
        
                ]]>
        </mx:Script>
        <mx:Binding source="(data as MyCustomClass)" source="myInternalData" />
        <mx:Label text="{myInternalData.myFunction()}" />

Hopefully that helps your item renderer problem.

You are correct. Functions can be "bound" BUT I think what Frederico was pointing out is that there are some important things to understand when binding with functions (which are stated in the document that you referenced.) It is not as easy as just putting the function in curly braces.

"You can use ActionScript functions as the source of data binding expressions when using a bindable property as an argument of the function. "

If you do not pass a parameter to the function then flex has no way of knowing when to update the function. You can do a quick test of this by running this test:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"; layout="vertical" horizontalAlign="center">
        <mx:Script>
                <![CDATA[
                
                        [Bindable]
                        public var myData:String = 'old data';
                        
                        private function myFunction(data:String = null):String{
                                return myData;
                        }
                        
                ]]>
        </mx:Script>
        <mx:Label text="{myData}" />
        <mx:Label text="{myFunction(myData)}" />
        <mx:Label text="{myFunction()}" />
        <mx:Button label="Test" click="myData = 'new data';" />
</mx:Application>

as you can see the first two labels will update correctly because they have a reference to some underlying data. When that data changes Flex knows to execute the function again. The other option (as you pasted in your last email) is to dispatch an event from a setter so that flex will know to update the function that relies on the set data:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"; layout="vertical" horizontalAlign="center">
        <mx:Script>
                <![CDATA[
                
                        private var _myData:String = 'old data';
                        
                        public function set myData(value:String):void{
                                _myData = value;
                                dispatchEvent(new Event("myDataChanged"));
                        }
                        
                        [Bindable]
                        public function get myData():String{
                                return _myData;
                        }

                        [Bindable(event="myDataChanged")]
                        private function myFunction(data:String = null):String{
                                return _myData;
                        }
                        
                ]]>
        </mx:Script>
        <mx:Label text="{myData}" />
        <mx:Label text="{myFunction(myData)}" />
        <mx:Label text="{myFunction()}" />
        <mx:Button label="Test" click="myData = 'new data';" />
</mx:Application>

As you can see all the labels now update properly.

- Kevin

Reply via email to