17 Replies Latest reply on Sep 19, 2011 11:37 AM by Flex harUI

    Why isn't binding binding?

    Jerry62712 Level 1

      I have a project.  It has several components in it.  The verbiage in the system can change from English to Spanish and back depending of if a user wants that.

       

      To do this I thought I would have the components populate the labels from a class that would remember the language being used.  I also want to collect data from the input form component and do calculations that will appear in the result (output) component, but that is for down the road after I get the initial problem fixed.

       

      The English Input Labels class is bindable and a singleton.

       

      The input component instantiates the English Input Labels class.  Then the fields on it are set by getters in the English Input Labels class.

       

      If the user clicks a button, that class via the setters in it is converted to Spanish from English.  This in turn should be reflected via the binding in the input component labels.

       

      What is happening is when I put in an initial value in the English Input Labels class, a singleton, it is reflected in the input component.  But I can't get the values to change programatically and be reflected in the binding.  The singleton changes, but the labels in the component don't.

        • 1. Re: Why isn't binding binding?
          pauland Level 4

          So, a new thread to continue your old one somewhere else?

           

          At a wild guess, I'd suggest your singleton may not actually be a singleton. Are you sure you are only instantiating one instance?

           

          There's nothing special from a binding point of view about singletons.

          • 2. Re: Why isn't binding binding?
            UbuntuPenguin Level 4

            Pauland made a great point, can we see your singleton, at least the class declaration and constructor.  I have run into issues where I thought my microarch

            itecture had created a single instance of a class, but in reality there were two so it appeared as if binding wasn't working, when in reality it was my own fault.

            • 3. Re: Why isn't binding binding?
              Jerry62712 Level 1

              Here is the singleton.  I modified the original after some advice by the nice people right here.  I've limited it to just a couple of properties and methods to save space.

              package VO
              {
                  /**
                   * @author Jerry Davidson
                   * 
                   * This static class holds the display values in the input form.
                   * It is read by InputForm.mxml and is set to either Spanish or
                   * English when the user clicks the language button.
                   * 
                   */    
              
                  [Bindable]
                  public class InputLabels
                  {
                      private static var instance:InputLabels;
              
                      // residence - household information panel
                      public var resPanelLabel:String = "Panel Label Init";
                      public var resCountLabel:String = "";
                      public var resExemptLabel:String = "";
                      public var changeLang:String = "mn";
              ...
                      public function InputLabels(access:SingletonEnforcer)
                      {
                          if (access == null)
                          {
                              throw new Error('Input Labels is called by its instance');
                          }
                      }
              
                      public static function getInstance():InputLabels
                      {
                          if (instance == null)
                          {
                              instance = new InputLabels(new SingletonEnforcer());
                          }
                          return instance;
                      }
              
                      // household residents ************************************************
                      public function getResPanelLabel():String
                      {
                          return resPanelLabel;
                      }
                      public function setResPanelLabel(str:String):void
                      {
                          resPanelLabel = str;
                      }
              
                      public function getResCountLabel():String
                      {
                          return resCountLabel;
                      }
                      public function setResCountLabel(str:String):void
                      {
                          resCountLabel = str;
                      }
              ...
                  }
              }
              
              class SingletonEnforcer
              {
                  // dummy so only one instance is allowed
              }
              

               

              and here is how it is used:

                ...
                <fx:Script>
                  <![CDATA[
              
                      import VO.ArrayValues;
                      import VO.InputData;
                      import VO.InputLabels;
              
                      [Bindable]  public var saveData:InputData = InputData.getInstance();
                      [Bindable]  public var getArrays:ArrayValues = ArrayValues.getInstance();
                      [Bindable]  public var getLabels:InputLabels = InputLabels.getInstance();
              
                      [Bindable]    // household information **********************************
                      public var housePanelLabel:String = getLabels.getResPanelLabel();
                      [Bindable]
                      public var resSizeLabel:String = getLabels.getResCountLabel(
              ...
              );
              

               

              In each case where I'm trying this I do the "getInstance()" and then use the setter methods to set the English or Spanish values and the getter methods to populate the form.

               

              I'm wondering if I should make the various singleton properties public and use them instead of the getter methods.

              • 4. Re: Why isn't binding binding?
                Jerry62712 Level 1

                Actually, if you read closer you will see this is a completely different subject than the other one.  One is about creating singletons and this is about how to bind variables.  It is true both have the words "singleton", "class" and "flex" in them of course.

                 

                I posted the singleton here and how it is used.  I'm hoping I just made some stupid mistake that can be fixed with just some egg on my face.  I'll take egg and a fix any day of the week.

                 

                I tried in the place where it is used to use a direct placement:

                                <DHSclasses:AutoResizableTextArea
                                    id="insuranceAndTaxesLabel"
                                    text="{getLabels.getExpInsTaxLabel()}"
                                    autoResize="true"
                                    editable="false"
                                    tabEnabled="false"
                                    textAlign="right"
                                    wordWrap="true"
                                    left="5"
                                    width="89%"/>

                 

                and an indirect one:

                         [Bindable]
                        protected var medExpLabel:String = getLabels.getExpMedExpLabel();

                ...

                               <DHSclasses:AutoResizableTextArea
                                    id="elderlyMedicalExpensesLabel"
                                    text="{medExpLabel}"
                                    autoResize="true"
                                    editable="false"
                                    tabEnabled="false"
                                    textAlign="right"
                                    wordWrap="true"
                                    left="5"
                                    width="89%"/>

                 

                I didn't see any difference as neither worked.

                 

                I put "[Bindable]" before the singleton class which I thought would make all properties bindable without having to put it before each of them.  I'm assuming that the methods will function in a bindable way.

                • 5. Re: Why isn't binding binding?
                  UbuntuPenguin Level 4

                  I'm probaly wrong, but I thought you could only bind to fields, including getters and setters.  You are binding to a wholesale function.  Try replacing "getExpInsTaxLabel()"  with a getter i.e " public function get explnsTaxLabel".

                  • 6. Re: Why isn't binding binding?
                    pauland Level 4

                    Binding works on value changes. A bindable variable changing value will  trigger a change event and anything bound to it will be updated. In most  of your code you do a one-off initialisation, retrieving a value from a  singleton and subsequently changes taking place inside the singleton  aren't being seen - there is nothing in place to update your bound variables. There is no binding on the getters and setters for the singleton.

                     

                    I would start writing getters and setters in the usual actionscript way rather than the older style, and bind them.

                     

                    [Bindable]

                    public function set myValue(newVal:String):void{

                         _myValue = newValue;

                    }

                     

                    public function get myValue():String{

                         return _myValue;

                    }

                     

                    Then you can bind directly to the attributes of the singleton

                     

                    something = {singletonClassInstance.myValue};

                     

                    It's a good practice to put "_" at the start of private variable names, to indicate that they are private.

                    • 7. Re: Why isn't binding binding?
                      Jerry62712 Level 1

                      Thanks for the tips.  I will use "_" as it seems like a good idea.

                       

                      Further, I tried changing the "gets" to using the variable just incase as you indicated the methods were not picking up the "[Bindable]" from the class.  I do see the labels now whereas I didn't before.  This was before I read your reply on making the "gets" bindable.  I haven't tried switching between the languages yet - one step at a time.

                       

                      One thing that wasn't working was the singleton for arrays.  It caused an error and that resulted in no binding there at all.  Since you know a lot about this stuff, I'll run it by you.  Here is the singleton array class reduced to one array (of only two):

                          [Bindable]
                          public class ArrayValues
                          {
                              import DHSclasses.FSLangEnglish;

                       

                              private var English:FSLangEnglish;
                              private static var instance:ArrayValues;

                       

                              // default English version values
                              // if the user clicks "Spanish" they will be replaced with those values
                              public var yesNoArray:Array = new Array('2','1');
                      ...

                       

                              public function ArrayValues(access:SingletonEnforcer)
                              {
                                  if (access == null)
                                  {
                                      throw Error("Array Values is called by its instance");
                                  }
                              }

                       

                              public static function getInstance():ArrayValues
                              {
                                  if (instance == null)
                                  {
                                      instance = new ArrayValues(new SingletonEnforcer());
                                  }
                                  return instance;
                              }

                       

                              public function getYesNoArray():Array
                              {
                                  return yesNoArray;
                              }
                              public function setYesNoArray(input:Array):void
                              {
                                  yesNoArray = input;
                              }

                      ...

                          }
                      }

                       

                      class SingletonEnforcer
                      {
                          // dummy so only one instance is allowed
                      }

                      When I tried to initialize the array with this:

                       public var yesNoArray:Array = new Array(English.getYesNo());     // public method
                      or
                      public var yesNoArray:Array = new Array(English.yesNo);          // public property

                      it would get an error at run time:

                      TypeError: Error #1009: Cannot access a property or method of a null object reference.
                          at VO::ArrayValues()[C:\FSCalc\Flex\FSCalc\src\VO\ArrayValues.as:23]
                          at VO::ArrayValues$/getInstance()[C:\FSCalc\Flex\FSCalc\src\VO\ArrayValues.as:39]

                      ...

                      I'm pretty sure this is just a case of my ignorance on the proper syntax, but it doens't cause any compile errors.

                      • 8. Re: Why isn't binding binding?
                        pauland Level 4

                        Look up the Syntax!

                         

                        use this:

                         

                        public var yesNoArray:Array = [English.yesNo];
                        • 9. Re: Why isn't binding binding?
                          GordonSmith Level 4

                          Why not use Flex's ResourceManager and .properties files to localize your application for multiple languages? You can write code like

                           

                          <s:Button label="{resourceManager.getString('myapp', 'greeting')}"/>

                           

                          and have the label update from "Hello!" to "Hola!" when you change from

                           

                          resourceManager.localeChain = [ "en_US" ]

                           

                          to

                           

                          resourceManager.localChain = [ "es_ES" ]

                           

                          Gordon Smith

                          Adobe Flex SDK Team

                          • 10. Re: Why isn't binding binding?
                            Jerry62712 Level 1

                            Thanks for your response.  Unfortuantely, it doesn't work.  Same error as before.  At least I now have 3 syntaxial wrong ways.

                             

                            I found a 4th, but that one was different.

                                 public var yesNoArray:Array = English.yesNo;

                            This doesn't produce an syntax error.  It doesn't work either.

                            • 11. Re: Why isn't binding binding?
                              Jerry62712 Level 1

                              This application may run on public PCs.  It is specific to Illinois so the "language" might be considered English, but in reality some people that will use it speak Spanish.  Any system that picks up the location (and therefore language) would be worthless due to the location being 100% Illinois.

                              • 12. Re: Why isn't binding binding?
                                Flex harUI Adobe Employee

                                You can control what locale is in effect.  It isn’t tied to the OS settings.

                                • 13. Re: Why isn't binding binding?
                                  Flex harUI Adobe Employee

                                  I think you were getting a runtime error, so it probably isn’t syntax.  What is English and when does it get initialized?

                                  • 14. Re: Why isn't binding binding?
                                    Jerry62712 Level 1

                                    It is quite possible that a number of our users are using PCs at the library.  Others may be using one from school.  Some will have their own PCs, but we are talking about people getting SNAP benefits so I suspect few have their own PCs.

                                    • 15. Re: Why isn't binding binding?
                                      Flex harUI Adobe Employee

                                      How are you deciding whether to show English or Spanish text?  However you are doing that, you can just as easily switch the locale instead.

                                      • 16. Re: Why isn't binding binding?
                                        Jerry62712 Level 1

                                        English is a reference to the class FSLangEnglish.  This class will have all the English texts that appear in the application.  There is a cooresponding FSLangSpanish.  Here is a place it is used.  This script will change the values in the input form including the two arrays (one is a Yes/No one and the other has more values in it.

                                        public function setEnglishInput():void

                                        {

                                            // This will set the input form text fields to English

                                            // See "SetEngTop" for setting the page header component & title/buttons

                                            // See "SetEngBot" for setting the page footer component & foot

                                            import DHSclasses.FSLangEnglish;

                                         

                                            import VO.ArrayValues;

                                            import VO.InputLabels;

                                         

                                            var English:FSLangEnglish = new FSLangEnglish();

                                            var setLabels:InputLabels = InputLabels.getInstance();

                                            var setArrays:ArrayValues = ArrayValues.getInstance();

                                         

                                            // uses VO which is bound to array variables

                                            setArrays.setYesNoArray(English.getYesNo());

                                            setArrays.setUtilityArray(English.getDropDownUtility());

                                         

                                            setLabels.setResPanelLabel(English.getHouseholdInformationLabel());

                                         

                                            setLabels.setResCountLabel(English.getResidenceSizeLabel());

                                        Here is a sample of what is in that class:

                                        package DHSclasses {

                                          public class FSLangEnglish

                                          {

                                            public function FSLangEnglish() {}    // dummy constructor

                                         

                                            private const language:String = "Español";

                                            public function getLanguage():String {

                                                return language;    }

                                         

                                           private const pageTitle:String =

                                                "SNAP Eligibility Calculator";

                                            public function getPageTitle():String {

                                                return pageTitle;    }

                                        ...


                                        public const yesNo:Array = new Array(["No","Yes"]);

                                        public function getYesNo():Array {


                                        return yesNo;}

                                        (sorry about that goofy formatting - I"m not putting it in that way)

                                        • 17. Re: Why isn't binding binding?
                                          Flex harUI Adobe Employee

                                          A simple test case will help determine the problem.