I’m working on a base framework for Flash projects at work using PureMVC, SWFAddress, and BulkLoader. I’ve gone back and forth for a while now on the issue of loading one 600k swf that contains all of your assets, or loading page assets as individual swfs, which I think is the better way. What I wanted to avoid was having to compile individual “functioning” swfs that aren’t really part of the system. I want to simply use swfs as asset libraries and nothing else. The problem comes when you go to add an object from your loaded library.
If I try to add a graphic asset from the external library to the stage in my mediator I’ll get an error because basically that object does not exist yet. After doing a bit of research yesterday I found a work-around that I don’t particulaly like, but it works.
First of all, you have to define an ApplicationDomain in your Loader — or in this case, BulkLoader — with a LoaderContext object:
var context:LoaderContext = new LoaderContext(false,ApplicationDomain.currentDomain);bulkLoader.add(HomeMediator.ASSETS,{context:context});bulkLoader.add(AboutMediator.ASSETS,{context:context});etc...
Then you have to use the handy getDefinitionByName method in flash.utils. I have to say, though, that as useful as this little bit of code it, I don’t really like it. It feels like a hack. But it works, so let me show you the difference. First, the old way:
var header_mc = viewComponent.addChild(new HomeHeader());header_mc.init({x:100, y:200, name:"header_mc"});
became:
var ClassName:Class = getDefinitionByName("HomeHeader") as Class;var header_mc = viewComponent.addChild(new ClassName());header_mc.init({x:100, y:200, name:"header_mc"});
I can tell you, I hated this right off the bat. The idea of adding another line of code for every graphic element I add to the stage made me cringe. You’ll notice I’ve got this init() method that I’m calling on my objects as well. I’ll explain that in a minute.
The final solution I came up with for addressing adding elements to the stage was to create a DisplayManager class with a single static method:
public static function attachObject(viewComponent:*, ClassName:String, initObject:Object = null):Object{ var _ClassName:Class = getDefinitionByName(ClassName) as Class; var _mc = viewComponent.addChild(new _ClassName());
if (initObject){ _mc.init(initObject); }
return _mc;}
which boils three lines of code in my mediators down to one:
var header_mc = DisplayManager.attachObject(viewComponent, "HomeHeader", {x:100, y:100, name:"header_mc"});
Lovely.
Ok, so let me quickly fill you in on the init() thing, which I thought I had posted on in the past, but it turns out I had only posted about the thought that lead up to it, simple proptery setting. I took this idea and created a very simple class, DisplayClip, that extends MovieClip and adds an init method that takes an initObject as a parameter and transfers those parameters to the MovieClip. I’ve got TypicalBtn and TypicalMenuBtn classes that extend DisplayClip, and I have to say it’s come in extremely handy.
package com.peteramayer.as3.display {
import flash.display.*; import flash.text.*; import flash.events.*;
public class DisplayClip extends MovieClip implements IEventDispatcher{
public function DisplayClip() { trace("[DisplayClip]"); }
public function init(initObj:Object ) { for (var prop in initObj) { this[prop] = initObj[prop]; } }
}
}