6 Replies Latest reply on Apr 14, 2009 4:40 AM by wvxvw

    Any Flex equivalent of "with"?

    Handycam Level 1

      In some other languages, I can use a "with" statement to avoid having to type the same thing over and over, as in this loop:

       

      private function createSteps():void{

      var numSteps:uint = dataXML.length;

      var recipeStep:CyorStep;

              for (var i:uint=0;i<numSteps;i++){

              this["step"+i].label= (i+1) +". "+ dataXML[i]..stepTitle;

      this["step"+i]..itemChoicesList = dataXML[i]..item;

      this["step"+i].stepTitle.text = dataXML[i].stepTitle;

      this["step"+i].stepPanel.title = dataXML[i]..prompt;

      this["step"+i].stepCaption.text = dataXML[i]..bodyText;

      this["step"+i].stepImage.source= "assets/"+i+".png";

      this["step"+i].minChoices = dataXML[i]..min;

      this["step"+i].maxChoices = dataXML[i]..max;

      this["step"+i].stepNumber = i;

      if (i == (numSteps-1)){

      this["step"+i].nextBtn.label = "FINISH";

      }

      this["step"+i].addEventListener("GO_PREVIOUS",prevStep);

      this["step"+i].addEventListener("ITEM_CHOSEN",updateItems); 

              }

             

            }

       

      Any way to do something similar in Flex/AS3?

        • 1. Re: Any Flex equivalent of "with"?
          wvxvw

          Well, first of all dynamic access is a bad practice, dynamic access without casting is kind of a as you ware throwing send in your wheels... And, sure, there is

           

          with (graphics) { 
               beginFill(0);
               drawRect(0, 0, 100, 100);
               ...
          }

           

          Construction.

          • 2. Re: Any Flex equivalent of "with"?
            Handycam Level 1

            I'm not sure I follow about the dynamic access.  I have x number of

            instances of the same component inside a view stack.  I originally

            tried to create them dynamically with addChild, but was having great

            difficulty accessing the date inside them.  So now as deadline looms I

            have fallen back to creating them by hand inside the viewstack (3 of

            them) and each of the 3 have to have the same thing done to them.

            Hence the loop.

             

            However, I am quite open for suggestions of a better or more proper way...

            • 3. Re: Any Flex equivalent of "with"?
              wvxvw Level 1

              Well, usually you want to avoid array-style (dynamic) access as this is:

              - slow (sealed properties of a class-object are stored in the has table which has faster access due to it's structure).

              I.e. mySprite.x is faster than myUntypedObject["someDynamicProperty"].

              - you create string literals, which have the only purpose of finding the real property.

              - you miss the code completion (as the code editor doesn't know what to expect after you type obj["prop"] - it can be anything...

               

              So, normally you do something like this:

              - put all the instances you want to loop through later into Array or Vector (vector isn't much faster, but it's faster for coding as you'll get autocompletion)

              - make them a Dictionary keys, that'd be even faster than Array or Vector.

               

              The average code would look like this:

               

              for each (var someObject:SomeType in arrayOfSomeObjects)

              {

                  someObject.doSomething(); // Here you both get the proper completion and some speed increacement

              }

               

              Usually, all framework components dispatch some event when they create another components, but, even if you don't know what even the component will dispatch, you may always add listener for "creationComplete" event dispatched from the component you create, like this:

               

              <?xml version="1.0" encoding="utf-8"?>
              <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
                  <mx:Script>
                      <![CDATA[
                          import flash.events.Event;
                          import mx.controls.Alert;
                          import mx.controls.Button;
                         
                          private var _listOfButtons:Array = [];
                          private function addMeToTheListOfButtons(event:Event):void
                          {
                              _listOfButtons.push(event.currentTarget);
                          }
                         
                          private function displayAllButtonsInTheList():void
                          {
                              var message:String = "";
                              for each(var buttonFromTheList:Button in _listOfButtons)
                              {
                                  message += "Label for this button: " + buttonFromTheList.label + "\r";
                              }
                              Alert.show(message);
                          }
                      ]]>
                  </mx:Script>
                  <mx:Repeater id="testRepeater">
                      <mx:dataProvider>
                          <mx:XMLList>
                              <node foo="bar"/>
                              <node foo="foo"/>
                          </mx:XMLList>
                      </mx:dataProvider>
                      <mx:Button
                          label="{testRepeater.currentItem.attribute('foo')}"
                          creationComplete="addMeToTheListOfButtons(event)"
                          click="displayAllButtonsInTheList()"
                          />
                  </mx:Repeater>
              </mx:Application>

              • 4. Re: Any Flex equivalent of "with"?
                Handycam Level 1

                Wow, that is very helpful thank you.

                 

                I was trying to do that originally, but my problem was I was unable to figure out how to access the components within the created component instances:

                 

                 

                private function createSteps():void{

                var stepNumber:uint = 1;

                var numSteps:uint = dataXML.length;

                 

                        for each(var step:XML in dataXML){

                var recipeStep:CyorStep = new CyorStep();

                mainViewStack.addChild(recipeStep);

                recipeStep.label = stepNumber +". "+ step.stepTitle;

                recipeStep.itemChoicesList = step..item;

                recipeStep.prompt.text = step.prompt;

                recipeStep.stepCaption.text = step.bodyText;

                recipeStep.stepTitle.text = step.stepTitle;

                 

                if (stepNumber == numSteps){

                recipeStep.nextBtn.label = "FINISH";

                }

                recipeStep.addEventListener("GO_PREVIOUS",prevStep);

                recipeStep.addEventListener("GO_NEXT",nextStep);

                stepNumber++

                }

                      }

                 

                In other words, after doing this I had my components, but I couldn't figure out how to access (for example) the second "recipeStep" instance --- or, more accurately, items inside that such as recipeStep1.stepTitle.text

                • 5. Re: Any Flex equivalent of "with"?
                  wvxvw Level 1
                  1. import flash.utils.Dictionary;
                  2. import flash.events.Event;
                  3. private var _hash:Dictionary = new Dictionary();
                  4. private var _recipies:Array = [];
                  5. private function createSteps():void
                  6. {
                  7.     var stepNumber:int = 1;
                  8.     var numSteps:int = dataXML.length;
                  9.     var recipeStep:CyorStep;
                  10.     for each (var step:XML in dataXML)
                  11.     {
                  12.         recipeStep = new CyorStep();
                  13.         _hash[recipeStep] = stepNumber; // assuming you run this loop only once,
                  14.         // otherwise invent some other unique identifier
                  15.         _recipies[stepNumber] = recipeStep;
                  16.         mainViewStack.addChild(recipeStep);
                  17.         recipeStep.label = stepNumber + ". " + step.stepTitle;
                  18.         recipeStep.itemChoicesList = step..item;
                  19.         recipeStep.prompt.text = step.prompt;
                  20.         recipeStep.stepCaption.text = step.bodyText;
                  21.         recipeStep.stepTitle.text = step.stepTitle;
                  22.         if (stepNumber == numSteps)
                  23.         {
                  24.             recipeStep.nextBtn.label = "FINISH";
                  25.         }
                  26.         recipeStep.addEventListener("GO_PREVIOUS", prevStep);
                  27.         recipeStep.addEventListener("GO_NEXT", nextStep);
                  28.         stepNumber++
                  29.     }
                  30. }
                  31. private function prevStep(event:Event):void
                  32. {
                  33.     trace(event.currentTarget); // This will be the item that produced
                  34.     // "GO_PREVIOUS" event.
                  35.    
                  36.     // We look up the target of this event in the array of all
                  37.     // possible targets using the dictionary key
                  38.     // while we know that key would be also that item
                  39.     // position within an array
                  40.    
                  41.     // alternatively, you could've used _recipies.indexOf(event.currentTarget)
                  42.     // to define how this current item relates to other items within an array.
                  43.     // it this case, the statement below would trace the same as the first
                  44.     // trace()
                  45.     // But, would we need to address the item which is not the .currentTarget
                  46.     // of this event, we would be avle to find it's relative position
                  47.     // in _recipies to the item that trigged the event.
                  48.    
                  49.     trace(_recipies[_hash[event.currentTarget]] as CyorStep).stepCaption);
                  50.    
                  51.     // or, if you know that the number of items is not dynamic,
                  52.     // you can make a switch-case like this:
                  53.    
                  54.     switch (event.currentTarget)
                  55.     {
                  56.         case _recipies[1]:
                  57.             trace("First item has trigged the prevStep() handler");
                  58.             break;
                  59.         case _recipies[2]:
                  60.             trace("Second item has trigged the prevStep() handler");
                  61.             break;
                  62.         default:
                  63.             trace("prevStep() handler was trigged by an item not in the _recipies array");
                  64.             break;
                  65.     }
                  66. }
                  • 6. Re: Any Flex equivalent of "with"?
                    wvxvw Level 1
                    1. import flash.utils.Dictionary;
                    2. import flash.events.Event;
                    3. private var _hash:Dictionary = new Dictionary();
                    4. private var _recipies:Array = [];
                    5. private function createSteps():void
                    6. {
                    7.     var stepNumber:int = 1;
                    8.     var numSteps:int = dataXML.length;
                    9.     var recipeStep:CyorStep;
                    10.     for each (var step:XML in dataXML)
                    11.     {
                    12.         recipeStep = new CyorStep();
                    13.         _hash[recipeStep] = stepNumber; // assuming you run this loop only once,
                    14.         // otherwise invent some other unique identifier
                    15.         _recipies[stepNumber] = recipeStep;
                    16.         mainViewStack.addChild(recipeStep);
                    17.         recipeStep.label = stepNumber + ". " + step.stepTitle;
                    18.         recipeStep.itemChoicesList = step..item;
                    19.         recipeStep.prompt.text = step.prompt;
                    20.         recipeStep.stepCaption.text = step.bodyText;
                    21.         recipeStep.stepTitle.text = step.stepTitle;
                    22.         if (stepNumber == numSteps)
                    23.         {
                    24.             recipeStep.nextBtn.label = "FINISH";
                    25.         }
                    26.         recipeStep.addEventListener("GO_PREVIOUS", prevStep);
                    27.         recipeStep.addEventListener("GO_NEXT", nextStep);
                    28.         stepNumber++
                    29.     }
                    30. }
                    31. private function prevStep(event:Event):void
                    32. {
                    33.     trace(event.currentTarget); // This will be the item that produced
                    34.     // "GO_PREVIOUS" event.
                    35.    
                    36.     // We look up the target of this event in the array of all
                    37.     // possible targets using the dictionary key
                    38.     // while we know that key would be also that item
                    39.     // position within an array
                    40.    
                    41.     // alternatively, you could've used _recipies.indexOf(event.currentTarget)
                    42.     // to define how this current item relates to other items within an array.
                    43.     // it this case, the statement below would trace the same as the first
                    44.     // trace()
                    45.     // But, would we need to address the item which is not the .currentTarget
                    46.     // of this event, we would be avle to find it's relative position
                    47.     // in _recipies to the item that trigged the event.
                    48.    
                    49.     trace(_recipies[_hash[event.currentTarget]] as CyorStep).stepCaption);
                    50.    
                    51.     // or, if you know that the number of items is not dynamic,
                    52.     // you can make a switch-case like this:
                    53.    
                    54.     switch (event.currentTarget)
                    55.     {
                    56.         case _recipies[1]:
                    57.             trace("First item has trigged the prevStep() handler");
                    58.             break;
                    59.         case _recipies[2]:
                    60.             trace("Second item has trigged the prevStep() handler");
                    61.             break;
                    62.         default:
                    63.             trace("prevStep() handler was trigged by an item not in the _recipies array");
                    64.             break;
                    65.     }
                    66. }

                    Sorry, I was fighting the line-height / margin / padding in my previous post. Now I won, but, somehow I cannot delete it now :) Mods, please, delete my previous post!