8 Replies Latest reply on Jul 28, 2010 6:38 AM by Anthony.R

    Lazy Loading Modules

    Anthony.R Level 2

      Hello,

       

      I have a project that uses Cairngorm 3 and am trying to implement a solution that loads modules on demand based on navigation events.  I am using version 0.8 of the Module library with Flex 3.5.

       

      In my case however the list of modules to eventually be loaded is determined at runtime.  After a login event fires a list of modules is determined.  For each module a ParsleyModuleInfo object is created and initialized and added to a collection.  This collection is then used as a data provider to a repeater which is a child of a view stack.  The repeater has one child which is a subclass of ViewLoader.  When the repeater repeats the automationName and info properties are populated from the data provider.

       

      Using this approach however for dynamically adding modules causes all modules to be downloaded and initialized.  I'd much rather prefer to have modules loaded only when an appropriate navigation event is fired.  I've read that the Navigation and Module libraries support lazy loading but am just unsure how to make use of it since my case is unique.

        • 1. Re: Lazy Loading Modules
          yderidde

          Hi,

           

          First of all I would really encourage you to migrate to the latest version of the Module Library which is version 0.11 as since version 0.10 we fixed a major issue in how styling get inherited in the modules.

           

          Now concerning the ability to lazy load the module you can have a look at the ModuleTest project available here http://opensource.adobe.com/svn/opensource/cairngorm3/trunk/libraries/ModuleTest/

           

          In there you will see that we dispatch a message called "PingMessage" thru the parsley dispatcher which contains a [ModuleId] Metadata. The moduleId defines a unique instance of a module. If you set the moduleId to the ViewLoader and specify the same moduleId in the message, you basically redirect the message to that specific ViewLoader.

           

          Using the ModuleId is not mandatory, if not specified, you will have to use the moduleRef property of the ModuleMessageInterceptor and therefore the message is going to be dispatched into every modules instances of that type. (eg. If you have 10 instances of ModuleA, the message is going to be dispatched to all 10)

           

          Here a little example of what need to be setup using the LazyModuleLoadPolicy :

           

          In your View:

           

          [Bindable]
          public var moduleManager:IModuleManager;
          [Bindable]
          [Inject(id="lazyLoadPolicy")]
          public var lazyLoadPolicy:ILoadPolicy;
          
          

          ...

          <cairngorm:ViewLoader id="moduleLoader"
               moduleId="myModuleId123"
               moduleManager="{ moduleManager }"
               loadPolicy="{ lazyLoadPolicy }"/>
          
          

           

          In your Parsley Context:

           

          To link the PingMessage to the LazyModuleLoadPolicy that is injected to your ViewLoader:

          <cg:LazyModuleLoadPolicyTag objectId="lazyLoadPolicy" type="{ PingMessage }" />
          
          

           

          To register the PingMessage as an inter-communcation message that need to travel to a module:

          <cg:ModuleMessageInterceptor
               type="{ PingMessage }" />
          
          

           

          The message (PingMessage):

          public class PingMessage
          {
               private var _moduleId:String;
          
               public function PingMessage(moduleId:String)
               {
                    this._moduleId = moduleId;
               }
               [ModuleId]
               public function get moduleId():String
               {
                    return _moduleId;
               }
          }
          
          

           

          You dispatch the message as follow:

          [MessageDispatcher]
          public var dispatcher:Function;
          
          ...
          
          dispatcher( new PingMessage("myModuleId123") );
          
          

           

          Hope It helps

           

          /yaniv

          1 person found this helpful
          • 2. Re: Lazy Loading Modules
            Anthony.R Level 2

            Thanks Yaniv I'll have a look.

             

            Does version 0.11 work with Flex 3.5?  The Flex 3 Module library in your Maven repository only seems to have version 0.8.

            • 3. Re: Lazy Loading Modules
              ledroff Adobe Employee

              Hello guys,

               

              I just added the missing flex3 releases.

              ...so now you'll have for Module for instance :

               

              Module for flex4(.1) :  http://opensource.adobe.com/svn/opensource/cairngorm3/maven-repository/com/adobe/cairngorm /module/0.11/

              Module for flex3(.5) : http://opensource.adobe.com/svn/opensource/cairngorm3/maven-repository/com/adobe/cairngorm /module-flex3/0.11/

               

              Cheers,

              François

              • 4. Re: Lazy Loading Modules
                Anthony.R Level 2

                Thanks for the help.  I'm in the process now of updating my Cairngorm libs to the latest in order to try out your suggestion.

                • 5. Re: Lazy Loading Modules
                  Anthony.R Level 2

                  Where did the progressView and errorView go form ViewLoader?  I was using these before to customize what appears while the module loads.  Once upgrading to the lastest module library these properties have disappeared.

                  • 6. Re: Lazy Loading Modules
                    yderidde Level 1

                    Hi Anthony,

                     

                    When we migrated the Module library to Flex SDK 4.x,  we took the opportunity to re-write the ViewLoader as a Spark component which is now named "ModuleViewLoader". This new component use the spark architecture which means that the look&feel is now separated into a Skin using states. The default skin for the ModuleViewLoader is ModuleViewLoaderSkin which can be found in the same package. If you want to change the look&feel you can create your own Skin based on the ModuleViewLoaderSkin.

                     

                    Now, concerning the SDK 3 ViewLoader, we decided that the ViewLoader would become a lightweight version compatible with Flex SDK 3 (and 4) that doesn't have any skinning either views such as errorView and progressView. However you can easily extends the ViewLoader to add such features if you need them or if your project is using SDK 4, I would recommend you to use ModuleViewLoader instead.

                     

                    I hope it clarify the difference between the ViewLoader and ModuleViewLoader ...

                     

                    Cheers,

                    /yaniv 

                    1 person found this helpful
                    • 7. Re: Lazy Loading Modules
                      Anthony.R Level 2

                      Thanks Yaniv.  As I'm stuck on Flex 3 for the time being I'll try your suggestion of extending ViewLoader.

                      • 8. Re: Lazy Loading Modules
                        Anthony.R Level 2

                        Hi Yaniv,

                         

                        I actually have one more question regarding lazy loading and navigation.

                         

                        In my application I am dynamically adding several ViewModule children to a ViewStack which has a Waypoint defined.  All the modules have landmarks defined in them so I'd like them to be apart of the Navigation structure.  Here is what I've noticed...

                         

                        Clicking a link in a toolbar dispatches a PingMessage to load the module and then also dispatches a NAVIGATE_TO event.  When this occurs I can see the module being loaded in the console but the navigation never occurs.  After some more digging I discovered that all my dynamically added ViewModules didn't get configured as part of the Navigation system since they were added after initialize.  To get around this after I've finished adding children to the ViewStack I manually dispatch its INITIALIZE event again.  When I do this however all the modules get loaded immediately instead of waiting for a PingMessage.  Clicking the same link from above does cause the navigation to work though.

                         

                        So my question then is...How can I get lazy loading AND navigation to work in the case where children are programmatically added to a ViewStack?

                         

                        I'm not really expecting Cairngorm to support this use case but was at least hoping for some suggestions on what could be extended to support it.

                         

                        Thanks again for your help.  I'm really enjoying working with Cairngorm/Parsley as an application framework and hope I'm not pushing it beyond where it was meant to go.

                         

                        Anthony