12 Replies Latest reply on Sep 16, 2011 5:32 PM by Flex harUI

    Vars, scoping in Flex

    sneakyimp Level 2

      I've got years of experience with AS3 but am very new to MXML.  I've downloaded Flash Builder 4.5 in the hope of building some mobile applications and am stumbling over the integration of Actionscript with MXML.  I need to dynamically build an elaborate game interface by drawing shapes.

       

      For some reason, Flash Builder tells me I have an error in the Actionscript here:

      <?xml version="1.0" encoding="utf-8"?>
      <s:ViewNavigatorApplication xmlns:fx="http://ns.adobe.com/mxml/2009" 
                                  xmlns:s="library://ns.adobe.com/flex/spark" firstView="views.HelloWorldHomeView">
          <fx:Declarations>
              <!-- Place non-visual elements (e.g., services, value objects) here -->
          </fx:Declarations>
      
          <fx:Script>
              <![CDATA[
      
                  var myString:String = "";
                  
                  // !!! error: 1120: Access of undefined property myString
                  myString = "";
                  
              ]]>
          </fx:Script>
      </s:ViewNavigatorApplication>
      
      

       

      I don't understand why this would be an error.  Additionally, I'm wondering why I cannot refer to the this object in code I enter in this MXML file.  The Flash Builder IDE complains in that case that "1042: The this keyword cannot be used in static methods. It can only be used in instance methods, function closures, and global code."

       

      Given that the Actionscript exists in the very first script in my application's MXML file, I would expect that "this" would refer to my application itself as if I had entered this actionscript on the first frame of my Flash Movie in the Flash IDE. Either that or the actionscript would be global.  But static?  How is this actionscript static?

       

      Is there any sort of tutorial that explains the idea of scope and how MXML scripts are scoped, I would certainly appreciate it.  I'm also interested in learning how best to organize my actionscript and MXML in my Flex projects.

        • 1. Re: Vars, scoping in Flex
          pauland Level 4

          In MXML all code must be inside a function and called from another function or via an event handler.

          1 person found this helpful
          • 2. Re: Vars, scoping in Flex
            sneakyimp Level 2

            That's weird.  Do you have any official links describing this in more detail?  I have a pretty dire need to understand scoping more.  For instance, if I want to generate new, dynamic objects, what objects and methods are at my disposal?

             

            I'm accustomed to setting a document class in the Flash IDE -- this means you can define an external actionscript file which the flash movie uses when it instantiates the movie clip.  I need to know the equivalent approach in MXML/Flex.

             

            For instance, when a view, MyNewView, gets pushed onto the navigation stack at the push of a button, I need to run some actionscript which will attach new, dynamic objects to the view.  These new dynamic objects are not attached to any particular object on the view.  They are attached to the view itself.

            • 3. Re: Vars, scoping in Flex
              Flex harUI Adobe Employee

              In theory, all code does not have to be inside a function, although that's a

              good practice.  MXML is just a markup for a subclass.  Use the

              -keep-generated-actionscript compiler option to see what it generates.  It

              will hopefully give you a better feel for what is going to happen with your

              script block.

               

              I generally avoid using bare code in a class definition even when doing

              straight ActionScript.

               

              -Alex

              1 person found this helpful
              • 4. Re: Vars, scoping in Flex
                GordonSmith Level 4

                >  if I want to generate new, dynamic objects, what objects and methods are at my disposal?

                 

                You just use the 'new' operator to create an instance of any class. The methods you can call on that instance are, of course, determined by the class. If the thing you're creating is visual, then you have to add it to the display list, typically with addElement(). So, for example, to add a button to a Spark application you'd write the following code inside some handler:

                 

                var b:Button = new Button();

                b.label = "OK";

                addElement(b);

                 

                Gordon Smith

                Adobe Flex SDK Team

                • 5. Re: Vars, scoping in Flex
                  GordonSmith Level 4

                  > I generally avoid using bare code in a class definition even when doing straight ActionScript.

                   

                  Alex says this because bare code executes at class initialization time, not at instance initialization time, and that is seldom what you want. For example, the original problem with myString is that it was declared as an instance variable, which doesn't exist until an instance is created, but then accessed by bare code as a implied static variable (since only statics exist at class initialization time). This is a very unfortunate quirk of AS3, and a future version of MXML will probably warn about, or disallow, bare code in <Script> blocks.

                   

                  Gordon Smith

                  Adobe Flex SDK Team

                  • 6. Re: Vars, scoping in Flex
                    sneakyimp Level 2

                    Thanks for the helpful response Flex harUI.

                     

                    I'm confused when you say that "MXML is just a markup for a subclass" ? To me, "subclassing" means I've written a class that extends some other class.  From what I've seen, MXML is kind of a declarative way to define my entire application, which I believe is an instance of ViewNavigatorApplication, as well as its constituent components such as a View.  Unless I'm mistaken the View class extends the SkinnableContainer and is not a subclass of ViewNavigatorApplication or vice versa.

                     

                    That tip for the -keep-generated-actionscript compiler flag is helpful.  For anyone else who wants to know, this compiler flag instructs the Flash Builder IDE to keep the automatically generated actionscript files (and other stuff) when building the SWF file. You can enable this in Flash Builder 4.5 for a given project by right-clicking the project and selecting Properties.  Then, select Flex Compiler and in the box where it says Additional Compiler Arguments you add a space and then paste in -keep-generated-actionscript=true.  Then, when you run/compile your project, take a peek in the bin-debug/generated folder and you should see a bunch of Actionscript files which will give you a much better idea of what is going on in your SWF.

                     

                    My goal here was not to use 'bare code' but rather to understand the relationship of my MXML script blocks to the Actionscript 3 scoping with which I am already familiar. The downside of relying on Flash Builder to generate my actionscript from MXML is that I no longer have control over the actionscript external to the class or the class declaration itself (including extends, implements, etc).  I could be missing something, but this seems to me like I'm ceding control to the IDE for my classes and I'm also having to learn a new paradigm for creating objects.

                     

                    Now I'm wondering which class functions I need to delcare to get something to run once my view is initialized.  Is it possible to define a constructor function in MXML for the auto-generated class?  Is there a naming convention for the auto-generated classes? Are there standard events for these auto-generated classes such as before object initialization and after object instantiation, etc.?

                    • 7. Re: Vars, scoping in Flex
                      GordonSmith Level 4

                      When you write MyApp.mxml as

                       

                      <s:Application>

                        ...

                      </s:Application>

                       

                      you are defining

                       

                      public class MyApp extends spark.components.Application.

                       

                      When you write MyButton.mxml as

                       

                      <s:Button>

                         ...

                      </s:Button>

                       

                      you are defining

                       

                      public class MyGroup extends spark.components.Button.

                       

                      The name of the class you are creating is the name of the MXML file (and the directory of the MXML file determines its package). The root tag in the MXML file determines the class you are extending.

                       

                      The <Script> is simply copied into the body of the class.

                       

                      Any instance tag with an id, such <s:Button id="b">, creates a public (and bindable) instance variable

                       

                      public var b:Button;

                       

                      in the class so that script methods and event handlers can refer to that instance.

                       

                      You cannot write a constructor for the MXML class.

                       

                      If you are extending a UIComponent class, then the important lifecycle events to learn about are preinitialize, initialize, updateComplete, creationComplete, and applicationComplete.

                       

                      Gordon Smith

                      Adobe Flex SDK Team

                      • 8. Re: Vars, scoping in Flex
                        GordonSmith Level 4

                        typo:

                         

                        public class MyGroup extends spark.components.Button

                         

                        should have been

                         

                        public class MyButton extends spark.componens.Button

                         

                        - Gordon

                        • 9. Re: Vars, scoping in Flex
                          Flex harUI Adobe Employee

                          If you look at the generated code, your app extended

                          ViewNavigatorApplication, and instantiated Views and added them as children.

                           

                          There are events and lifecycle methods for you to learn about.  There are

                          examples, training videos and books.  It depends on what best fits your

                          learning style.

                           

                          By using a framework like Flex, and using MXML instead of AS, you are

                          definitely giving up control.  You are using code written by someone else in

                          the hope that it will save you time.  For most people it does, and that's

                          why we've been successful.

                          • 10. Re: Vars, scoping in Flex
                            sneakyimp Level 2

                            Gordon thank you too for the excellent detail.  Alex's tip on -keep-generated-actionscript was really helpful and corroborates what you've said. My "trace" function for instance was included in the generated actionscript at the class level.  Your code to instantiate a button was also helpful, but I'm still wondering a bit about scope related issues and object persistence.

                             

                            Suppose for a moment that I were to adapt your button-adding code to create some elaborate matrix of dynamically created objects not in the main MXML block for the application but instead in a <script> block in a view.  For example in MyNewView.mxml in the HelloWorld example. The view MyNewView is added when you click a button on the default view for my app:

                            <?xml version="1.0" encoding="utf-8"?>
                            <s:View xmlns:fx="http://ns.adobe.com/mxml/2009" 
                                    xmlns:s="library://ns.adobe.com/flex/spark" title="HomeView">
                                <fx:Declarations>
                                    <!-- Place non-visual elements (e.g., services, value objects) here -->
                                </fx:Declarations>
                                
                                <s:VGroup width="100%" height="100%" verticalAlign="middle"
                                          horizontalAlign="center">
                                    <s:Label text="Hello World!"/>
                                    <s:Button label="Continue" click="navigator.pushView(MyNewView)" styleName="next" />
                                </s:VGroup>
                            </s:View>

                             

                            Then in myNewView, I create a <script> block.  Seems pretty obvious that if I want to add a button in there using Actionscript that I should not be trying to add a button at the static/declaration level in my code but rather inside some class function.  Which function though? Keep in mind I'm not adding a simple button or shape here but probably an instance of an elaborate class I define myself.  Additionally, I'll probably need to supply MyNewView with some data.  I see that the pushView method can accept a data parameter so I'm guessing that's a way to pass information in.  Unfortunately, I don't see how to define code in my view to parse this data object and begin creating interface elements.  Additionally, I wonder about the memory consumption of these objects I dynamically create -- are they destroyed when popView runs?  Do I need to create a destructor to clean them up?

                             

                            I realize that some of this is learning to deal with the view navigator class and some of it is learning the Flash Builder eccentricities.  Any assistance would be much appreciated.

                            • 11. Re: Vars, scoping in Flex
                              sneakyimp Level 2

                              Oops...I type slowly because I'm reading code, documentation, etc.  Very helpful posts thank you.

                               

                              Sadly, the Flash Builder approach seems like quite a learning curve for me.  I do not doubt the success of the product and crave its mobile app development features. I'm just looking to understand it as quickly as possible or perhaps how to find a workflow that suits an old AS3 hand.  Given that, book suggestions are welcome.  Obviously, I consider "flex for dummies" or some such thing too simple.  Any good books or learning resources on the internet?

                              • 12. Re: Vars, scoping in Flex
                                Flex harUI Adobe Employee

                                The good and bad of AS3 is that you can use it in an object-oriented manner

                                or not.  I don't know what kind of AS3 projects you've worked on in the

                                past, but from the questions you are asking, my sense is that you might

                                benefit from putting into practice my two recommendations for working with

                                OO code.  My number one recommendation in the OO world is to trust the

                                layers underneath you until they screw you over, then go digging.  My number

                                two recommendation is to train your brain to see patterns.

                                 

                                I would start with a non-mobile app and look at all of the examples on

                                flexexamples.com and in our doc.  You should start to see the patterns for

                                how children get added and removed and what events are commonly used to

                                launch other code.  You would trust that the child tags in MXML get

                                instantiated in time for 99% of the use cases, but not necessarily in the

                                constructor, because of the way the framework subsystems work.  And you

                                would trust Flash Builder to help you manage the code.

                                 

                                You've already had to trust that the Flash Player will do things in a

                                particular way and that the browser it lives in will launch the Flash Player

                                in a particular way.  Flex is another layer on top of the Flash Player for

                                you to trust to see how far you can get following common patterns.

                                 

                                You can find past threads on the forums about good education materials.  I

                                can't recommend any since I learned before there were books, but I did

                                review Chafic's book many years back.