10 Replies Latest reply on Nov 19, 2010 1:06 AM by drkstr_1

    FlexGlobals.topLevelApplication and SWFLoader Issue

    DanieSpreeth

      Hi All,

       

      Im currently sitting with an issue which I am pretty sure there should be an easy solution to, but I am new to Flex and AS.

       

      I developed a small Flex project which compiles into a SWF (Flex 4 & AS 3). When running this SWF by itself, it works perfectly.

       

      Then I created another project with a SWFLoader, and I loaded the small SWF into this. When running this I am getting errors, because in one of the classes of the original project which works when running by itself (not hosted) I am using references to "FlexGlobals.topLevelApplication".

       

      When running the original SWF by itself, "FlexGlobals.topLevelApplication" return the correct values, but when running it as a hosted app via SWFLoader, "FlexGlobals.topLevelApplication" references the parent app, not the hosted app.

       

      How do I change the code to ALWAYS refer to the "current" swf, not the one which it is being hosted in. I need this SWF to work both by itself AND hosted in another swf using SWFloader.

       

      I hope I described the issue in such a way that you understand what I am getting at.

       

      Using parentApplication instead of topLevelApplication also does not work since that also references the parent instead of the "current".

       

      Help would be appreciated!

       

      Danie Spreeth

        • 1. Re: FlexGlobals.topLevelApplication and SWFLoader Issue
          Flex harUI Adobe Employee

          You can load into a sibling applicationdomain using Marshall Plan techniques

          or walk the document/parentDocument chain until you hit the application.  It

          depends a bit on what your code is actually going to do

          • 2. Re: FlexGlobals.topLevelApplication and SWFLoader Issue
            DanieSpreeth Level 1

            Hi!

             

            Thanks for the response - this has now become a major impediment for me...

             

            I hear what you're saying, but it's not completely what I'm looking for. I knew this might be hard to explain, so let's do it properly this time.

             

            I have 2 Flex Builder projects - completely seperate.

             

            APPLICATION NUMBER 1

            This basically consists of 1 mxml file and a whole bunch of custom classes (.as files).

            This application has 3 states, and all state-related operations happens within the mxml file, except for in one case where in one of the classes, I need to change the application's state. This code looks like this:

                 FlexGlobals.topLevelApplication.currentState = "MainState";

             

            This application works fine as a stand-alone SWF - and it should be able to run by itself. So no problems thus far.

             

            APPLICATION NUMBER 2

            This application has NO CODE, it's only an mxml file with a SWFLoader in it - referencing the compiled SWF for Application 1.

             

            The line of code above now fails, because the topLevelApplication is now Application 2, not 1.

             

            The only possible solution I can think of right now would be to put the line of code above in a Try...Catch block (Im a senior c# developer - new at this though), and when the line of code fails, the catch block would then go through all the childapplications of the parent application until it finds Application 1 and then go from there. This seems excessive to me though. Surely there has to be a way to always reference the CURRENT application, no matter where it is executing from.

             

            Hope I am making sense...?

            • 3. Re: FlexGlobals.topLevelApplication and SWFLoader Issue
              drkstr_1 Level 4

              Most would consider using FlexGlobals.topLevelApplication to be bad OOP design. Your current problem is a case in point.

               

              Instead of creating a hard reference to topLevelApplication, you should bubble up an event that get's captured in the application scope and triggers a state change.

              • 4. Re: FlexGlobals.topLevelApplication and SWFLoader Issue
                DanieSpreeth Level 1

                Hi drkstr_1,

                 

                I think your post and my one above happened more or less at the same time. Have a look at what I said there.

                 

                There is a few references to topLevelApplication that I would need to fix (referencing app width, height and some other properties) but since I am making an effort to stick to OOP principles as much as possible, I would now REALLY like to know the correct way of doing this.

                 

                I need to be able to work with the "current" application - changing states, checking properties, etc, from within my custom classes. That's what it comes down to.

                 

                Hope u can help!

                • 5. Re: FlexGlobals.topLevelApplication and SWFLoader Issue
                  drkstr_1 Level 4

                  Well there are many different techniques at your disposal, but here is my simplified take on it...

                   

                   

                  Any time a class has to reference a parent or an external namespace, you are making those two classes tightly coupled. This can introduce breakage to the internal workings of a class when external changes are made (kind of like what your problem is). As a rule of thumb, I try to never have a class tell another class what to do unless that class is encapsulated within it (IE. a property of the class, or a descendant on it's display list).

                   

                  So in your situation, instead of having a child tell it's parent when to change states, a loosely coupled approach would be for that child to tell it's parent when something has changed internally, and the parent should decide if it should change it's state or not. Or more directly, find the code where you would normally tell the the application to change state, and dispatch an event instead. Add an event listener in the application and add the code to change it's own state in the handler. If the component is not a direct child of the application, you can tell the event to bubble to the top. As for checking properties, have the parent tell it's children what information they need to know.

                   

                   

                  Feel free to give specifics if you're still having trouble deciding on the best way to make your classes loosely coupled.

                  • 6. Re: FlexGlobals.topLevelApplication and SWFLoader Issue
                    Flex harUI Adobe Employee

                    Use of the parentApplication property will work for most display objects.

                    You can skim through the Modules presentation on my blog if you want to know

                    more about ApplicationDomains and how they are affecting you.  SWFLoader and

                    ModuleLoader are mostly similar in this regard.

                     

                    I'm not a fan of bubbling events.

                     

                    If you use an MVC architecture, and name the controller uniquely, that might

                    be a better approach.

                    1 person found this helpful
                    • 7. Re: FlexGlobals.topLevelApplication and SWFLoader Issue
                      drkstr_1 Level 4

                      Aye.

                       

                      Events are the simple approach. I actually prefer MVC as well, for larger projects requireing a more complicated application framework.

                       

                      The important thing I think is to limit the dependency on external classes (except of course in certain design patterns where specific classes are intentionally tightly coupled). There are many different application frameworks or techniques out there that accomplish that goal. These are just a matter of personal preference though.

                      1 person found this helpful
                      • 8. Re: FlexGlobals.topLevelApplication and SWFLoader Issue
                        Flex harUI Adobe Employee

                        Events are simple.  Bubbling events break encapsulation and will bubble up

                        and through to the top-level application.  Small projects often tend to get

                        larger.

                         

                        But sometimes, you just gotta get something out the door, so what ever works

                        for you.  Of course, I reserve the right to say "I told you so".

                        • 9. Re: FlexGlobals.topLevelApplication and SWFLoader Issue
                          DanieSpreeth Level 1

                          Hi,

                           

                          Thanks to both you guys - I am now dispatching a custom event from the class and added a listener to the mxml file that contains the original Application where the states exist that needs to be changed. The custom event then passes the new state name and it all works ok now.

                           

                          I can now clearly see the benefits of this approach. My custom class is no longer depending on an external class with certain properties to exist - code is much more robust this way.

                           

                          Thanks again!

                           

                          Danie.

                          • 10. Re: FlexGlobals.topLevelApplication and SWFLoader Issue
                            drkstr_1 Level 4

                            Events are simple.  Bubbling events break encapsulation and will bubble up

                            and through to the top-level application.  Small projects often tend to get

                            larger.

                             

                            I would agree that bubbling is a bad idea. I don't know why I even suggested it. I guess I should have added that ideally, a parent should never have to react to changes more than one (maybe two) levels down the chain. Otherwise, some reconsideration probably needs to be done on how the components are designed.