3 Replies Latest reply on Jul 27, 2007 3:38 PM by ntsiii

    Warning: Unable to Bind to Property

    almis-
      I am stuck trying to narrow down a problem that causes a "unable to bind to property" warning. Running this code (debug mode) in Flex Builder 2.0.1 produces the following output in the console window:

      warning: unable to bind to property 'label' on class 'XML' (class is not an IEventDispatcher)
      warning: unable to bind to property 'label' on class 'XML' (class is not an IEventDispatcher)

      Any help would be greatly appreciated!

      <?xml version="1.0" encoding="utf-8"?>
      <mx:Application xmlns:mx=" http://www.adobe.com/2006/mxml">
      <mx:XML id="items" xmlns="">
      <items>
      <item label="label1"/>
      <item label="label2"/>
      </items>
      </mx:XML>
      <mx:VBox>
      <mx:Repeater id="rp" dataProvider="{items.item}">
      <mx:Label text="{(rp.currentItem as XML).@label}"/>
      </mx:Repeater>
      </mx:VBox>
      </mx:Application>
        • 1. Re: Warning: Unable to Bind to Property
          peterent Level 2
          Data binding works because it uses events. When you put [Bindable] before a variable, the Flex compiler generates code which watches that variable and whenever it changes, uses dispatchEvent to send a notification. Whenever you use { } as a binding expression the Flex compiler generates code which listens for those events and changes the destination (that thing using { }) to the new value.

          That message you are getting is saying that the XML class does not implement the IEventDispatcher class which means that there is no events dispatched whenever a property of the XML changes. We can't put binding and events on everything because it would really slow down the application - can you imagine every time you used a for-loop an event was dispatched when the loop control variable changed?

          So what's the solution? In this there isn't a good and easy way to eliminate the problem. And it actually isn't a problem here because your XML is static and won't change. If you were going to use the XML dynamically you'd probably wind up reading it via some data service and then you wouldn't have the problem.

          Now let's say you have your own class:

          public class MyData {
          public var a:String;
          public var b:Number;
          }

          And then you want to use it:

          [Bindable] public var test:MyData;
          ...
          <mx:Label text="{test.a}" .. />

          You'll get the warning, "Data binding will not be able to detect changes to a" - why is that? Well, your MyData class doesn't produce any events when the public variable a is changed. So if at some point you do: test.a = "hello" the Label will not show the new value.

          The quick fix to this is to place [Bindable] before the class declaration of MyData:

          [Bindable]
          public class MyData { ...

          This will make the Flex compiler modify your class to implement IEventDispatcher and generate code to dispatch events whenever any of the variables are changed.

          Hope that clears it up.
          • 2. Re: Warning: Unable to Bind to Property
            almis- Level 1
            Thank you for a great explanation! I also came across another solution in a different forum. It was suggested to modify:

            <mx:Label text="{(rp.currentItem as XML).@label}"/>

            to:

            <mx:Label text="{XML(rp.currentItem).@label}"/>

            This eliminated the warning message, however I wonder whether this creates any unecessary overhead in the case of static XML data that does not require biding (the real project where this problem appears is large and CPU performance is becoming an issue).

            Thanks again!
            • 3. Re: Warning: Unable to Bind to Property
              ntsiii Level 3
              Actually, you CAN bind to XML. The problem (one is a misleading warning) is that the Repeater.currentItem is an OBJECT, and you cannot bind to an object, because it has insufficient data type information.

              But the currentItem object contains XML. To bind to it, you need to convert/cast it to XML. Like this example:
              htmlText="{XML(repAccOptions.currentItem).text}" (if "text" is a sub node )
              or
              htmlText="{XML(repAccOptions.currentItem).@text}" (if "text" is an attribute)

              Tracy