The following is a quick start guide on how to get RobotLegs working on top of the Gaia Flash Framework written by Steven Sacks. In later articles, I’ll show how to use per-Gaia-page Contexts, a visual example, as well as cover Enterprise scenarios. For now this should get you up and running in 10 minutes.
What is RobotLegs?RobotLegs is a MVCS framework for Flex & pure AS3 applications. You can use with Flash as well. I call it PureMVC done right. She’s still not at version 1, but is really close (docs in progress).
What is Gaia?
The Gaia Flash Framework is the Ruby on Rails for building Flash websites. You can code generate your entire Flash website in seconds. It has modules, SEO, page navigation, and deep-linking all built-in, amongst other things.
Why?
Gaia is great for building websites, but it’s just a platform for you to build on, a bunch of helpful scaffolding; it doesn’t prescribe a way to build your applications. Specifically, you have to write your own code for Business logic and Application/Domain logic. You still have to write code to hit back-end services, parse the returning XML/JSON/AMF, and act on that data.
This is where an application framework like RobotLegs comes in. You’re domain model goes in the Model classes, your Business logic goes in the Service classes, and your Domain/Application logic goes in your Commands & Mediators. You setup your shiz in your Context class(es), like PureMVC’s ApplicationFacade
Gaia builds your site, and RobotLegs makes it work with dynamic data.Requirements
Before we get to the “How”, you need to know 2 requirements first. This may scare some people off.
- You need both mxmlc & Flash CS4 or CS3
- Your application must be AS3
RobotLegs requires compiling in mxmlc because of the custom metadata tags. Flash CS3 & CS4 do not currently support the -keep-as3-metadata mxmlc compiler parameter, thus, you must compile your RobotLeg’s implementation code using mxmlc (via Flex Builder 2, 3, Flash Builder 4, FDT, FlashDevelop, etc.).
While you can compile Gaia to an SWC in Flash CS4, and then re-compile via a Library linkage in mxmlc, this defeats the purpose of using the Gaia workflow in Flash. I understand this is deal killer for many automated build/continuous integrations of Enterprise applications, so I’ll cover optional build scenarios in a future article.
Flash CS4 is required because it allows you to link to external libraries, in this case, Flex created SWC’s. You could utilize Flash CS3, and just add a class path to the RobotLegs classes since you’ll typically only be using the interfaces in your Flash/Gaia specific code. Both Flash CS3/CS4 will be exporting AS3 code since RobotLegs is for AS3, so you can’t use Flash 8 and export to AS2.
I currently do not have access to Flash CS5 alpha/beta to determine if it’s integration with Flash Builder 4 demoed at MAX 2009 would help in this instance, nor do I know if it can -keep-as3-metadata.
Quickstart Preface
The Quickstart may appear intimidating at 15 steps. If you know Flex Builder/FlashDevelop, Flash, Gaia, and RobotLegs, you’ll do just fine, it’s not that bad. Additionally, you only need to do this stuff once.
The rest of your project, you’ll spend in your code editor. You can also link the Main file in Flex Builder to get code hinting on it. The only time you go to Flash is to do Control + Enter.
GIT-R-DONE!!!11oneone
Quickstart
1. Setup your Gaia site.
2. Open up your main.fla in Flash.
3. In Flash CS4, go to File > Publish Settings, click the Flash tab, click the Settings button next to AS version, click the Library Path tab, and link to the RobotLegs.swc. In Flash CS3, just add a class path to the RobotLegs source code directory.
4. Save your main.fla.
5. Create an ActionScript 3 project in Flex/Flash Builder, FDT, or FlashDevelop. Point it to the same directory your Gaia project lives. I suggest changing bin-debug to bin since that’s what Gaia uses. Although it’ll generate a SWF, it’s hereafter referred to as a “module” SWF since Gaia will load it in and use it’s pre-compiled classes.
6. Create your own main class, differently named (ie not “Main.as”), and put next to Gaia’s Main.as. This will be where your RobotLegs code lives.
7. Link to the RobotLegs.swc as a Library. If you are in Flex/Flash Builder, you may wish to link to the RobotLegsLib Library project instead. If so, I put this in Gaia’s lib folder next to the FLA’s that Gaia puts there. The image below shows linking to the Library Project.
8. Create a “MainContext” ActionScript class where ever you’d like in your package structure. Might I recommend something other than Gaia’s pages directory, like “com.company.project.robotlegs.contexts”. In this class, you register your modules, in this case, your Gaia pages that actually need Mediators. Here’s mine:
package com.jxl.gaiarobotlegs.robotlegs.contexts
{
import com.jxl.gaiarobotlegs.pages.IAboutPage;
import com.jxl.gaiarobotlegs.robotlegs.mediators.AboutMediator;
import flash.display.DisplayObjectContainer;
import org.robotlegs.mvcs.Context;
public class MainContext extends Context
{
public function MainContext(contextView:DisplayObjectContainer)
{
super(contextView);
}
public override function startup():void
{
mediatorMap.mapModule('com.jxl.gaiarobotlegs.pages::AboutPage', IAboutPage, AboutMediator);
super.startup();
}
}
}
Notice the mapModule method goes “Your Gaia Page class as a String”, “The interface the Gaia Page class and the Mediator share”, and “The RobotLegs Mediator class”. NOTE: In older builds of RobotLegs, they are using the fully qualified class name which is ::AboutPage, not .AboutPage (more info). I have a hacked version locally which accepts a normal package path of “pages.AboutPage” vs. “pages::AboutPage”. Yes, I’ve asked the RobotLegs authors to fix this.
9. Create 1 more class and 1 corresponding interface: a Mediator class for whatever Gaia page you’ll be mediating, and an interface of the same name with the I prefix. Example: If you’re creating an “About Us” page for your site, you’ll probably have an about page node in your site.xml, and thus a corresponding FLA. Create an “IAboutUs” interface, and an “AboutUsMediator” class that implements the interface. Your Gaia “AboutUsPage” class will also implement the “IAboutUs” interface. This is how RobotLegs will communicate to your Gaia code via the Bridge Pattern (more info on why).
Here’s the interface:
package com.jxl.gaiarobotlegs.pages
{
public interface IAboutPage
{
function setAboutText(value:String):void;
}
}
Here’s the Mediator:
package com.jxl.gaiarobotlegs.robotlegs.mediators
{
import com.jxl.gaiarobotlegs.pages.IAboutPage;
import flash.events.TimerEvent;
import flash.utils.Timer;
import org.robotlegs.mvcs.Mediator;
public class AboutMediator extends Mediator
{
[Inject]
public var aboutPage:IAboutPage;
private var timer:Timer;
public function AboutMediator()
{
super();
}
public override function onRegister():void
{
timer = new Timer(3 * 1000);
timer.addEventListener(TimerEvent.TIMER, onTick, false, 0, true);
timer.start();
}
private function onTick(event:TimerEvent):void
{
timer.stop();
timer.removeEventListener(TimerEvent.TIMER, onTick);
timer = null;
aboutPage.setAboutText('Blah blah blah,nthis is from RobotLeg's 'AboutMediator'');
}
}
}
Thing to note in the above is the Dependency Injection via the [Inject] tag does IAboutPage vs. AboutPage; this ensures mxmlc doesn’t attempt to compile Gaia code into your module SWF.
10. Any events your Gaia About Us page will emit, put in the IAboutUs interface. Any data your Gaia About Us page needs to have set on itself, implement a setter or a method in the IAboutUs interface. This’ll ensure your About Us page class in Gaia and your AboutUsMediator won’t compile until you implement those methods, nor will your AboutUsMediator RobotLegs class. Yes, I know events in interfaces aren’t enforced, but that doesn’t mean you shouldn’t do it.
Here’s the Gaia AboutPage class:
package com.jxl.gaiarobotlegs.pages
{
import com.gaiaframework.api.*;
import com.gaiaframework.debug.*;
import com.gaiaframework.events.*;
import com.gaiaframework.templates.AbstractPage;
import flash.display.*;
import flash.events.*;
import flash.text.TextField;
import gs.*;
public class AboutPage extends AbstractPage implements IAboutPage
{
public var copyTextField:TextField;
public function AboutPage()
{
super();
alpha = 0;
//new Scaffold(this);
}
// called by RobotLegs's AboutPageMediator
public function setAboutText(value:String):void
{
copyTextField.text = value;
}
override public function transitionIn():void
{
super.transitionIn();
TweenLite.to(this, 0.3, {alpha:1, onComplete:transitionInComplete});
}
override public function transitionOut():void
{
super.transitionOut();
TweenLite.to(this, 0.3, {alpha:0, onComplete:transitionOutComplete});
}
}
}
Notice the implementation of IAboutPage. Since Gaia FLA’s by default have “../src” set in their class path, it’ll share the same class path with your ActionScript project. The only class it’s importing form that code, however, is the interface, which is a few 300 bytes or so once compiled into the SWF. If you’re clever, you could use External Libraries in CS4, but that’s out of scope for this article.
11. Open up your main.as file in your editor of choice. First, create a mainContext class reference, like:
private var mainContext:IContext;
12. Override init and do no call super.init. Instead, write code to load in your RobotLegs SWF that your ActionScript project will create in bin. You can use a Loader, your own wrapper class, extend Main to abstract away these details in a base class… whatever you want. I used a Loader for this example. Ensure you load the classes into the same ApplicationDomain so Gaia can share and use these classes, as well as any loaded SWF’s that need them.
var loaderContext:LoaderContext = new LoaderContext(false, ApplicationDomain.currentDomain);
moduleLoader.load(new URLRequest('GaiaRobotLegs.swf'), loaderContext);
13. In your Event.COMPLETE function, snatch your MainContext class from the loaded SWF, instantiate it, and pass the stage in, and call super.init to let Gaia know you’re done, like so:
private function onComplete(event:Event):void
{
const mainContextClassName:String = 'com.jxl.gaiarobotlegs.robotlegs.contexts.MainContext';
try
{
var mainContextClass:Class = moduleLoader.contentLoaderInfo.applicationDomain.getDefinition(mainContextClassName) as Class;
mainContext = new mainContextClass(stage) as IContext;
}
catch(err:Error)
{
trace('Failed to find class: ' + err);
}
super.init();
}
You use the stage so any DisplayObject added to the DisplayList will be checked to see if it has an associated Mediator. Yes, I know OOP Purists will groan at this; don’t worry, I’ll offer a more pure solution later. Remember, Gaia is typically used in Agencies with 2 week deadlines vs. 4 months; this is more than good enough for that crowd.
14. In your main ActionScript project class, define a dependency variable; this is strictly to ensure your RobotLegs code is compiled into the “module SWF”. Assuming you have Build Automatically on in Flex Builder, it should make your SWF in the bin folder for you once you save. Here’s mine:
package
{
import com.jxl.gaiarobotlegs.robotlegs.contexts.MainContext;
import flash.display.Sprite;
public class GaiaRobotLegs extends Sprite
{
private var mainContext:MainContext;
public function GaiaRobotLegs()
{
super();
}
}
}
15. Test your Gaia project in Flash.
Conclusions
As you can see, all you need to do now is code all your code in Flex Builder (or editor of choice), and anytime you need to compile your site, you just go back to main.fla in Flash and hit Control + Enter.
You’ll also notice I create one “global” context here. Reiterating, this is good enough for most design agencies as not every Gaia page will need a Mediator, and most Gaia pages aren’t that complex View’s anyway.
For the purists, in a future article I’ll explain how you can modify the Gaia template files, and configure your Context classes via the Gaia site.xml externally. This ensures that the details of a Gaia page registering it’s own Context, or simply just creating a single Context + Mediator for itself, are self-contained and as strongly-typed as possible.
For those building Enterprise sized sites with automated build processes, I’ll later go into how you can integrate a Gaia site into your build process.
Thanks
Just a quick thanks to Steven for helping answer my Gaia architecture questions, and to the RobotLegs crew for helping me work out the details of how it could be done.
"
Hi Tim,
ОтветитьУдалитьAll working fine except for its throwing this runtime error when testing:
Failed to find class: Error: Mediator Class does not implement IMediator - [class IAboutPage]
..although it does. Any idea?