A Robotlegs Flash Site Tutorial
Robotlegs is a light-weight, pure AS3 micro-architecture that has developed some intense devotion amongst the Flash community recently. Created by Shaun Smith, it provides a mechanism for wiring your objects together in a decoupled way, and through the use of automated metadata based dependency injection, Robotlegs removes boilerplate code in an application.
If you’re familiar with PureMVC, you’ll find lots of similarities in Robotlegs and then some – cool features such as Dependency Injection. In this tutorial, I shall demonstrate how to build a typical Flash site with Robotlegs, similar to the one in my PureMVC Flash Site tutorial. We shall examine how to set up a Robotlegs application to load an xml file and send user events from the navigation to the framework.
Using Robotlegs with Flash CS3 / CS4
Since Robotlegs relies on custom metadata for its dependency injection and Flash CS3/CS4 don’t support compiling custom metadata, Robotlegs is more suited for a workflow that doesn’t rely on the Flash IDE for compilation. However, the bundled SwiftSuspenders DI solution does provide a way to configure injection points using XML, allowing for Robotlegs usage in Flash CS3/CS4 compiled projects. Helmut Granda has written a detailed tutorial on how to configure the SwiftSuspenders XML_CONFIG to enable this.
1. Examine the asset.fla
In this example, the FLA is purely used to generate a SWC containing the font assets which will be imported into the application.
2. The RobotlegsFlashSite document class
The document class registers the Georgia and Helvetica fonts by creating the respective font instances. It also creates an instance of the ApplicationContext class.
package
{
import Georgia;
import Helvetica;
import flash.display.*;
import flash.text.Font;
import com.hubflanger.robotlegsdemo.ApplicationContext;
public class RobotlegsFlashSite extends Sprite
{
protected var context:ApplicationContext;
public function RobotlegsFlashSite()
{
// Sets the stage to NO_SCALE mode.
stage.scaleMode = StageScaleMode.NO_SCALE;
// Register the fonts
var georgia:Font = new Georgia();
var helvetica:Font = new Helvetica();
// Creates an instance of ApplicationContext
context = new ApplicationContext(this);
}
}
}
3. The ApplicationContext class
The Context lies in the heart of a Robotlegs implementation, providing the mechanism by which the implementation’s tiers will communicate. The Context provides three functions within an application: initialization, de-initialization, and creates the central event bus for communication. Although an application is not limited to a single Context, for many use cases one Context is sufficient.
The ApplicationContext class extends the base Context class in the Robotlegs framework. Its constructor accepts an instance of the RobotlegsFlashSite document class which is assigned to the variable contextView. Later on, we shall see how contextView is accessed throughout the application.
In a Robotlegs implementation, we typically override the startup() method to set up all the mappings for dependency injection, views and events. Here, we map a Singleton of SiteModel and an instance of SiteDataService which implements the ISiteDataService interface to the Injector. This makes them available to other classes in the application via the [Inject] metadata.
We then map 3 view classes (Header, Navigation and SectionContainer) to their respective Mediators by calling the mapView() method of the MediatorMap instance. In Robotlegs, a Mediator performs similar functions as ones in PureMVC. A Mediator provides a bridge between the framework and the View Component it’s responsible for. It passes along framework events to its view component and sends framework events in response to events dispatched by its view component. By putting application-specific logic in the Mediator, we de-couple the view component from the application’s implementation.
Finally, we call the mapEvent() method of the CommandMap instance to map 3 events to their respective Commands. The ContextEvent.STARTUP_COMPLETE event is dispatched by the framework upon completing execution of the Context’s startup() method. Here, we map the LoadDataCommand class to handle this event.
package com.hubflanger.robotlegsdemo
{
import com.hubflanger.robotlegsdemo.model.SiteModel;
import com.hubflanger.robotlegsdemo.controller.*;
import com.hubflanger.robotlegsdemo.service.*;
import com.hubflanger.robotlegsdemo.events.*;
import com.hubflanger.robotlegsdemo.view.*;
import com.hubflanger.robotlegsdemo.view.components.*;
import flash.display.DisplayObjectContainer;
import org.robotlegs.mvcs.Context;
import org.robotlegs.base.ContextEvent;
public class ApplicationContext extends Context
{
public function ApplicationContext(contextView:DisplayObjectContainer)
{
super(contextView);
}
override public function startup():void
{
// Map a Singleton of SiteModel
injector.mapSingleton(SiteModel);
// Map an instance of SiteDataService
injector.mapClass(ISiteDataService, SiteDataService);
// Map the Views and Mediators
mediatorMap.mapView(Header, HeaderMediator);
mediatorMap.mapView(Navigation, NavigationMediator);
mediatorMap.mapView(SectionContainer, SectionContainerMediator);
// Map the Events and Commands
commandMap.mapEvent(ContextEvent.STARTUP_COMPLETE, LoadDataCommand, ContextEvent, true);
commandMap.mapEvent(SystemEvent.INIT_VIEW, InitViewCommand, SystemEvent, true);
commandMap.mapEvent(UserEvent.NAV_CLICK, SectionSelectedCommand, UserEvent, false);
// Invoke the superclass' startup() method
super.startup();
}
}
}
4. The LoadDataCommand class
As intended by the command mapping, the LoadDataCommand command responds to the Context’s STARTUP_COMPLETE event. It creates an instance of SiteDataService using the [Inject] metadata. In its execute() method, we call the loadData() method of the SiteDataService instance to initiate the loading of xml data.
package com.hubflanger.robotlegsdemo.controller
{
import com.hubflanger.robotlegsdemo.service.ISiteDataService;
import org.robotlegs.mvcs.Command;
public class LoadDataCommand extends Command
{
[Inject]
public var siteDataService:ISiteDataService;
override public function execute():void
{
siteDataService.loadData();
}
}
}
5. The SiteDataService class
In Robotlegs, Model and Service classes extend the base Actor class to inherit functionality for communicating with the framework. A Model encapsulates and provides an API for data and sends event notifications when the data model has been changed. A Service communicates with the outside world through web services or file access and dispatches system events in response to external events.
In our SiteDataService class, we access the SiteModel singleton via the [Inject] metadata assigning it to the model variable. The loadData() method creates a URLLoader instance and loads the xml.
In the loadCompleteHandler event handler, we parse the xml
package com.hubflanger.robotlegsdemo.service
{
import com.hubflanger.robotlegsdemo.model.vo.SectionVO;
import com.hubflanger.robotlegsdemo.model.SiteModel;
import com.hubflanger.robotlegsdemo.events.SystemEvent;
import flash.events.Event;
import flash.net.*;
import org.robotlegs.mvcs.Actor;
public class SiteDataService extends Actor implements ISiteDataService
{
[Inject]
public var model:SiteModel;
public function SiteDataService()
{
//
}
public function loadData():void
{
var loader:URLLoader = new URLLoader();
loader.addEventListener(Event.COMPLETE, loadCompleteHandler);
loader.load(new URLRequest("assets/data.xml"));
}
private function loadCompleteHandler(event:Event):void
{
var loader:URLLoader = event.target as URLLoader;
loader.removeEventListener(Event.COMPLETE, loadCompleteHandler);
var xml:XML = new XML(event.target.data);
model.header = xml.header.text();
var sections:XMLList = xml.sections.section;
for each (var section:XML in sections) {
var sectionVO:SectionVO = new SectionVO(section.@id,
section.label.toString(),
section.content.toString());
model.sectionsList.push(sectionVO);
model.sectionsHash[sectionVO.id] = sectionVO;
}
model.defaultSection = model.sectionsList[0].id;
dispatch(new SystemEvent(SystemEvent.INIT_VIEW, false));
}
}
}
February 17th, 2011 at 3:41 pm
[...] is a quick modification of hubflanger’s useful Robotlegs AS3.0 Site tutorial. I’m expanding her service class to use a content loading library called [...]
February 18th, 2011 at 11:45 am
[...] on the previous Robotlegs entry. The original source code is generously provided by hubflanger. I’m modifying her code to show images using two popular asset loading & animation [...]