6 Replies Latest reply on Mar 31, 2008 10:50 PM by Sreenivas R

    Data binding object question

    Craig Grummitt Level 3
      I have set up a Repeater to display XML data. One field, called rsvpStatus, is a boolean, returning as either Y or N. I would prefer to display something like YES or NO. so i thought i could set up the text field like so:

      <mx:Text text="{Constants.yesNoTranslator[data.rsvpStatus]}"/>

      and elsewhere set up an associative array that translate Y/N into YES/NO such as:

      [Bindable]
      public static var yesNoTranslator:Object={N: "No",Y: "Yes"};

      I am being warned by Flex Builder that:
      "Data binding will not be able to detect changes when using square bracket operator. For Array, please use ArrayCollection.getItemAt() instead."

      despite this warning, it seems to be working.

      my question is:
      Do i put up with this warning and assume that it is unecessary, or is there a good reason for changing the structure of my code?

      Cheers
      Craig
        • 1. Re: Data binding object question
          Sreenivas R Adobe Employee
          I think you can ignore the warning.

          The warning is (may be) saying that in case you change the value of N or Y then it won't be able to detect the changes. You need to use a ObjectProxy for it as Object won't dispatch propertyChange events.

          The warning is refeering to a context where yesNoTranslator is an Array not an Object.
          • 2. Re: Data binding object question
            Bayani Portier Level 1
            The best way to go about it is as follows:

            [Bindable]
            public function get rsvpStatus():Boolean
            {
            return data.rsvpStatus=="Y";
            }

            public function set rsvpStatus(value:Boolean):void
            {
            //if you need bindback, pop it here otherwise use the dummy
            var dummyVar:int=9;
            }

            <mx:Text text="{this.rsvpStatus}"/>

            That way you are accessing the variable in the state that you want, with a lightweight getter/setter as an object proxy.

            Hope it helps
            • 3. Re: Data binding object question
              Craig Grummitt Level 3
              thanks for the feedback.

              i am finding it a little difficult to translate your suggestions to my code. in addition to the line i had above, i sometimes display data from within a repeater. Here are two examples:
              <mx:Text text="{Constants.yesNoTranslator[data.rsvpStatus]}"/>
              <mx:Text text="{Constants.yesNoTranslator[repeater.currentItem.rsvpStatus]}"/>

              Would the object proxy be required on yesNoTranslator(as Sreenivas suggested) or rsvpStatus(as bayani suggested)?

              if it is required on rsvpStatus(with getters/setters) that seems to be getting quite complicated as it is a property within a repeater's data object stored as an xml document.

              if it is required on yesNoTranslator that seems a little unecessary as it is a constant.

              if i decide to not ignore the warning, Sreenivas, and simply store yesNoTranslator as an objectProxy, how do i extract data from this now? Excuse my ignorance of objectProxies, but is there the equivalent of ArrayCollection.getItemAt()?

              Thanks again for your time!
              Craig
              • 4. Data binding object question
                Sreenivas R Adobe Employee
                The warning is more related to the fact that the compiler is not taking any action for the item inside the square bracket as it cannot be evaluted similar to a function.

                When {} binding is done compiler tries to generate a 'Binding' for each item within the braces. For example

                { x.y().z.a } would generate binding for x, for y, for z and for a.

                Because of the square brackets the compiler is stopping at that point and saying ' I cannot proceed further with this binding'.

                It is however suggesting that if yesNoTranslator was an array the develper can consider making it a ArrayCollection and calling getItemAt.

                The ObjectProxy would help only if there is going to be a change.
                There is no difference between accessing a property from a Object to ObjectProxy.

                That is the syntax would remain yesNoTranslator.N for both of the following cases.

                public static var yesNoTranslator:Object={N: "No",Y: "Yes"};

                public static var yesNoTranslator:ObjectProxy= new ObjectProxy({N: "No",Y: "Yes"});

                If you very much want to get rid of the warning you need to do the following

                <mx:Text text="{yesNoTranslator(data)}"/>

                <mx:Script>
                <![CDATA[
                public function yesNoTranslator(data:Object):String
                {
                return (data.rsvpStatus == "N") ? "No" : "Yes" ;
                }

                ]]>
                </mx:Script>
                • 5. Re: Data binding object question
                  Craig Grummitt Level 3
                  good one thanks for that Sreenivas i'm a lot clearer on this all now.
                  it all got me thinking - it might make sense to create a new class, say 'ObjectCollection' extending ObjectProxy with a 'getItemAt' method to make binding easier on objects in situations such as these:
                  (apologies but no Attach code button for some strange reason)


                  <?xml version="1.0"?>
                  <mx:Application xmlns:mx=" http://www.adobe.com/2006/mxml">
                  <mx:Text text="{yesNoTranslator.getItemAt(rsvpStatus)}"/>
                  <mx:Script>
                  <![CDATA[
                  [Bindable]
                  public var yesNoTranslator:ObjectCollection=new ObjectCollection({Y:"Yes",N:"No"});
                  [Bindable]
                  public var rsvpStatus:String="Y";
                  ]]>
                  </mx:Script>
                  </mx:Application>


                  package
                  {
                  import mx.utils.ObjectProxy;

                  public class ObjectCollection extends ObjectProxy
                  {
                  public function ObjectCollection(item:Object=null, uid:String=null, proxyDepth:int=-1)
                  {
                  super(item, uid, proxyDepth);
                  }
                  [Bindable(event="propertyChange")]
                  public function getItemAt(index:String):Object {
                  return(this[index]);
                  }
                  }
                  }
                  • 6. Re: Data binding object question
                    Sreenivas R Adobe Employee
                    This can be a simple class as well (no need to inherit from ObjectProxy) if the properties are going to remain constant.