Need Flex Migration Help?
- Adobe ends Flash player support in 2020
- Flex apps will no longer function
- We can help migrate your app
An embarrassingly long time ago I was sitting with Jeff Tapper at Max when we first heard about support for dynamic modules in Flex. I leaned over and said, ‘The first thing I am going to do tonight is build a ViewStack that supports modules.’ Well, it wasn’t the first (or 300th) thing I did, but I finally got around to actually fleshing it out. The observant reader will note that Modules in Flex are loaded with a ModuleLoader and that ModuleLoader is a LayoutContainer that supports delayed instantiation so you can already add modules to a ViewStack without reading the rest of this post. Those still reading will agree that the most basic implementation of a module is as follows: You generate a component that extends mx:Module. This code is compiled into a swf. This swf is dynamically loaded into your application when needed. It arrives and is shoved into a nice little container. You play with it and (sometimes) remove enough reference that it is one day garbage collected, ending its life and this cycle. I want more from my modules. Actually, perhaps ‘I want different’ from my modules is more accurate. I want my modules to be composed of a large number of classes which extend from all sorts of classes, whether they are visual or non-visual. When I load a module, I want access to these new classes, but I don’t necessarily want to instantiate them. When I add the visual ones to some display list, I want to control where, when and how. What I really want is dynamic libraries. In Flex and Actionscript if it doesn’t already exist, I can usually make what I want. So, I made some extensions to the Module classes and infrastructure that I call the Library classes. Here is a break down of the key pieces. ILibrary ? Library interface. All modules that wish to work with this infrastructure must implement the ILibrary interface. LibraryLoader ? A peer to the ModuleLoader. LibraryLoader is an event dispatcher, not a visual object. It loads a library from a URL, and readies that library for use. Further, it defines a single new method getDefinitionByName which accepts a string and returns an object from the library. It mirrors the functionality of flash.utils.getDefinitionByName for the contents of this loaded module. The actual modules I create extend the ModuleBase class, as opposed to Module, and simply contain a single type reference to each definition I want included:
var ref1:path.SomeComponent; var ref2:other.path.ReferenceClass; They also implement ILibrary and hence contain the implementation of the getDefinitionByName method as discuss above. It would be ideal if this could be included by inheritance but there are some ugly (buggish) reasons why that doesn’t work quite right. I digress. This allowed me to load modules and just use them as resource libraries in a simple and convenient little way. I could load a module, grab a class, instantiate it and add it to any display list anywhere, such as a viewstack. Life was good, but I thought I could take it just a bit further. So, I also created ILibraryContainer ? interface implemented by any Container that would like to add children from a library with a nice one step method. It requires one method:
function addChildByName( name:String ):void; which adds a child to that container based on a definition name and/or a URL plus definition name. All this method really does is the work of loading a module, getting the requisite resource and instantiating it for you, but it does simplify the implementation. Any container that implements this interface can add a child with the following syntax.
box.addChildByName("http:// www.somernadomurl.net/myModule.swf?net.digitalprimates.MyContainer"); which effectively loads the module found at this URL and instantiates and adds the class to the container. When applied to ViewStack this allows one to add children from various module libraries in short order. So, for fun, I made a LibraryViewStack and LibraryTabNavigator. You can call this method on either of these two entities to dynamically add children from any module. This is a great solution for ActionScript, but what about loading this all from MXML? Well, I need to leave something for the next post. The source for all of this is enclosed. There are three projects, one for a small sample app. One that contains part of the digital primates flex library and one that creates a sample module. Please note, in a real implementation, you would be concerned about excluding files from the module based on linking, etc. This is not done here. ML Download