11 Replies Latest reply on Aug 18, 2009 11:14 AM by Jens Wegar

    Flex scoping problem + example

    lathoudero

      Hi,

      I'm making a jump from AS2 to Flash Builder 4, and I'm loving it!

      But right now I'm stuck in something seemingly trivial it's frustrating me.

      Basically, I have my application, calling a Form defined in a separate mxml file.

      Now I want to call a function defined in the main application from this child-form, in this case, triggering a state-change.

      See example with source on:

      http://www.budgetnavigator.nl/test/bob/

       

      Declaring a public function apparently isn't enough to access it from a child...

      Creating a static function IS accessible from the child, but can't change 'local' settings in the parent.

       

      I'm sure it's something basic.. can someone point me in the right direction?

       

      Thanks!!

        • 1. Re: Flex scoping problem + example
          David_F57 Level 5

          try this

           

           

           

           [Bindable] public function callLocalFunction()....

           

           

           

           

          David.
           
          

           

          [edit] also in the child you could use parentApplication.callLocalFunction();

          • 2. Re: Flex scoping problem + example
            lathoudero Level 1

            Unfortunately, [Bindable] doesn't resolve anything in this case. I get an addittional warning that: [Bindable] is a parameter for functions that aren't getter or setter.

             

            BUT!

            "parentApplication.callLocalFunction();"

            works perfectly! Thanks David!

             

            So does:

            "parentDocument.callLocalFunction();"

             

            This saved me for now, but I still don't understand why "MainWindow.callLocalFunction()" doesn't work, when a function is "public".

             

            And I found this confusing line in the manual:

            "You can access the top-level application using the application property of the Application class."

             

            so.. how to access the top-level application?

            "application.callLocalFunction();" doesn't exist....

            Nor "Application.callLocalFunction();"

            or "MainScreen.application.callLocalFunction();"

            What am I missing?

            • 3. Re: Flex scoping problem + example
              GordonSmith Level 4

              > I still don't understand why "MainWindow.callLocalFunction()" doesn't work, when a function is "public".

               

              This would work if you made callLocalFunction() a 'static' function so that it belongs to the MainWindow class itself:

               

              public static function callLocalFunction()

               

              If you leave out the 'static' keyword, it is an 'instance' function that belongs to a particular instance of the MainWindow class, and therefore you have to invoke it on a particular instance.

               

              Gordon Smith

              Adobe Flex SDK Team

              1 person found this helpful
              • 4. Re: Flex scoping problem + example
                GordonSmith Level 4

                Is MainWindow your application? If so, do

                 

                Application.application.callLocalFunction();

                 

                Gordon Smith

                Adobe Flex SDK Team

                1 person found this helpful
                • 5. Re: Flex scoping problem + example
                  lathoudero Level 1

                  ok. I understand.

                  But how come a "public static function" of MainWindow.mxml can't access an instance of "public function", of the same MainWindow.mxml class?

                  Should I call the instance function differently?

                   

                  //This is some actionscript in MainWindow.mxml
                              public function callLocalFunction():void { 
                                  if (currentState == "State1") {
                                      currentState="new_state";
                                  } else {
                                      currentState="State1";
                                  }
                              }//works perfectly!
                  
                              public static function callLocalFunction2():void {
                                  //currentState="new_state"; // Doesn't work
                                  //callLocalFunction();//Doesn't work
                                  //parentDocument.callLocalFunction();//Doesn't work
                                  //Application.application.callLocalFunction();
                              }
                  
                  
                  • 6. Re: Flex scoping problem + example
                    lathoudero Level 1

                    Hi Gordon, thanks again for your help.

                    Unfortunately,

                    import spark.components.Application;
                    Application.application.callLocalFunction();
                    

                    OR

                    <?xml version="1.0" encoding="utf-8"?>
                    <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
                                   xmlns:s="library://ns.adobe.com/flex/spark"
                                   xmlns:mx="library://ns.adobe.com/flex/halo"
                                   minWidth="1024"
                                   minHeight="768"> 
                    <fx:Script>
                            <![CDATA[
                              Application.application.callLocalFunction();
                            ]]>
                        </fx:Script>
                    ...

                     

                    doesn't work. (Error 1119: undefined property through static Class).

                    It DOES exist if I import mx.core.Application;

                     

                    So I have to use:

                    <?xml version="1.0" encoding="utf-8"?>
                    <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
                                   xmlns:s="library://ns.adobe.com/flex/spark"
                                   xmlns:mx="library://ns.adobe.com/flex/halo"
                                   minWidth="1024"
                                   minHeight="768">
                        <fx:Script>
                            <![CDATA[
                                import mx.core.Application;
                                mx.core.Application.application.callLocalFunction();
                            ]]>
                        </fx:Script>
                    ...
                    

                     

                    But it's a bit weird...

                    Is "Application.application"  a missing feature in Flex 4?

                    • 7. Re: Flex scoping problem + example
                      lathoudero Level 1

                      Flash Builder debugger answered my question:

                      3608: 'application' has been deprecated since 4.0.  Please use 'FlexGlobals.topLevelApplication'.

                       

                      So, correct me if I'm wrong, the way to access public instances of functions in the "Main application" from a Child window is like this:

                      MainWindow source :

                       

                      <?xml version="1.0" encoding="utf-8"?>
                      <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
                                     xmlns:s="library://ns.adobe.com/flex/spark"
                                     xmlns:mx="library://ns.adobe.com/flex/halo"
                                     minWidth="1024"
                                     minHeight="768">
                          <fx:Script>
                              <![CDATA[
                                  public function callLocalFunction():void {
                                      if (currentState == "State1") {
                                          currentState="new_state";
                                      } else {
                                          currentState="State1";
                                      }
                                      
                                  }
                              ]]>
                          </fx:Script>
                      ....
                      

                       

                      ChildWindow source :

                      <s:Group xmlns:fx="http://ns.adobe.com/mxml/2009"
                               xmlns:s="library://ns.adobe.com/flex/spark"
                               xmlns:mx="library://ns.adobe.com/flex/halo"
                               width="400"
                               height="150"
                               baseColor="#0066FF">
                      
                          <fx:Script>
                              <![CDATA[
                                  import mx.core.FlexGlobals;
                                  protected function button1_clickHandler(event:MouseEvent):void {
                                      FlexGlobals.topLevelApplication.callLocalFunction();
                                  }
                              ]]>
                          </fx:Script>
                      ...
                      
                      • 8. Re: Flex scoping problem + example
                        rfrishbe Level 3

                        Yep, that looks correct.  The reason why Application.application is deprecated is beause there are many Application classes now--mx.core.Application, spark.components.Application, and the AIR versions--and we don't want to have to link in mx.core.Application if you don't need it.  So always try to use FlexGlobals.topLevelApplication instead.

                        • 9. Re: Flex scoping problem + example
                          Jens Wegar Level 1

                          It seems you've gotten your original question answered, but just as general advice I wanted to point out that you should try to avoid situations in your application design where you're calling a method in a parent class from a child. This makes your child object (in this case the form) more coupled to the parent object and thus less reusable. In your case you could for instance instead have the main application object listen for a click event from the button in the form and then react on that instead. Or you can have the form dispatch a custom event which the main application listens for. This way the form doesn't need to know anything about the main application.

                          • 10. Re: Flex scoping problem + example
                            lathoudero Level 1

                            Wow.. THIS was an eye-opener for me! Flex became a lot simpeler now!

                            Thanks Jens!

                             

                            MainScreen code:

                            <?xml version="1.0" encoding="utf-8"?>
                            <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
                                           xmlns:s="library://ns.adobe.com/flex/spark"
                                           xmlns:mx="library://ns.adobe.com/flex/halo"
                                           xmlns:ui="ui.*"
                                           minWidth="1024"
                                           minHeight="768"
                                           currentState="State1"
                                           applicationComplete="init()">
                                <s:states>
                                    <s:State name="State1" />
                                    <s:State name="new_state" />
                                </s:states>
                                <s:layout>
                                    <s:VerticalLayout />
                                </s:layout>
                                <fx:Script>
                                    <![CDATA[
                                        private function init():void {
                                            newscreen1.myChildButton.addEventListener(MouseEvent.CLICK, callLocalFunction);
                                        }
                            
                                        private function callLocalFunction(event:MouseEvent):void {
                                            change_state();
                                        }
                            
                                        protected function change_state():void {
                                            if (currentState == "State1") {
                                                currentState="new_state";
                                            } else {
                                                currentState="State1";
                                            }
                                        }
                                    ]]>
                                </fx:Script>
                                <ui:ChildScreen id="newscreen1" />
                                <mx:Label includeIn="new_state" text="Changed to NEW STATE!!!!!" fontSize="36" />
                                <mx:Spacer height="47" includeIn="State1" />
                                <s:Button label="MainScreen Button" click="change_state()" />
                            </s:Application>
                            

                             

                            ChildScreen code:

                            <?xml version="1.0" encoding="utf-8"?>
                            <s:Group xmlns:fx="http://ns.adobe.com/mxml/2009"
                                     xmlns:s="library://ns.adobe.com/flex/spark"
                                     xmlns:mx="library://ns.adobe.com/flex/halo"
                                     width="400"
                                     height="150"
                                     baseColor="#0066FF">
                                <s:layout>
                                    <s:BasicLayout />
                                </s:layout>
                                <mx:Form x="0"
                                         y="0"
                                         width="100%"
                                         height="100%"
                                         backgroundColor="#0092F9">
                                    <mx:FormHeading label="Heading" />
                                    <mx:FormItem label="Tekst">
                                        <s:RichEditableText text="Lorem ipsum dolor sit amet" />
                                    </mx:FormItem>
                                    <mx:FormItem>
                                        <s:Button id="myChildButton" label="ChildScreen Button" />
                                    </mx:FormItem>
                                </mx:Form>
                            </s:Group>
                            

                             

                            Voila!

                             

                            In retrospect, I feel... a bit dumb...

                            like...

                            riding on a horse sitting backwards, wondering where I should hold on to.

                             

                            Thanks for pointing this out, Jens.

                            ;-)

                             

                            HiHo Silver! Away!

                            • 11. Re: Flex scoping problem + example
                              Jens Wegar Level 1

                              No problem, glad I could help