Skip to content
robotlegs edited this page Sep 14, 2010 · 25 revisions

Robotlegs: A pure AS3 micro-architecture for Flash and Flex

Robotlegs is a lightweight AS3 MVCS Micro-Architecture inspired by PureMVC. Robotlegs was created to provide a small, loosly coupled application framework that is easy to test. Where other frameworks are plagued with coupling and Singletons, Robotlegs has none. Bolier plate? Robotlegs avoids it. It is the framework you’ve been looking for.

Installation

Grab the latest SWC file from this page:

Flex/FlashBuilder:

Drop the following SWC file into your “libs” folder:

  • RobotLegsLib.swc

If you are building a plain ActionScript project you might need to create the “libs” folder manually:

Right click the project, and create a New Folder called “libs”.
Right click the project, open “properties”, “Flex Build Path”, “Library path”, “Add SWC Folder…”, and add the folder “libs”.

Other IDEs or Editors:

Include the necessary SWC file in your build path.

Terminology

Robotlegs uses the same terminology as PureMVC for many of it’s components and concepts, such as:

Mediators, View Components, Proxies and Commands

Collectively, these are referred to as Framework Actors.

Usage

The Context

Typically, when starting a new project, you extend the default mvcs Context and override the startup() method.

Inside the startup() method you bind a couple of Commands to a startup event and then dispatch that event.

    public class HelloFlexContext extends Context
    {
    	public function HelloFlexContext( contextView:DisplayObjectContainer )
    	{
    		super( contextView );
    	}
    	
    	override public function startup():void
    	{
    		commandMap.mapEvent( PrepModelCommand, ContextEvent.STARTUP, ContextEvent, true );
    		commandMap.mapEvent( PrepControllerCommand, ContextEvent.STARTUP, ContextEvent, true );
    		commandMap.mapEvent( PrepServicesCommand, ContextEvent.STARTUP, ContextEvent, true );
    		commandMap.mapEvent( PrepViewCommand, ContextEvent.STARTUP, ContextEvent, true );
    		commandMap.mapEvent( StartupCommand, ContextEvent.STARTUP, ContextEvent, true );
    		eventDispatcher.dispatchEvent( new ContextEvent( ContextEvent.STARTUP ) );
    	}
    }

Instantiate the Context and pass it a reference to your view. For a Flex application it might look like this:

    <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" preinitialize="onPreInitialize()">
    	<mx:Script>
    		<![CDATA[
    			import net.boyblack.robotlegs.demos.helloflex.HelloFlexContext;
    			
    			private var context:HelloFlexContext;
    			
    			private function onPreInitialize():void
    			{
    				context = new HelloFlexContext( this );
    			}
    		]]>
    	</mx:Script>
    </mx:Application>

If you are building a plain ActionScript application, your main Sprite (entry point) might look like this:

    package
    {
    	import flash.display.Sprite;
    	import net.boyblack.robotlegs.demos.hello.HelloContext;
      
    	public class HelloActionScript extends Sprite
    	{
    		private var context:HelloContext;
		    
    		public function HelloActionScript()
    		{
    			context = new HelloContext( this );
    		}
    	}
    }

By default, a Context will automatically execute it’s startup() method when it’s View Component is added to the Stage.

Commands

Robotlegs make use of native Flash Player events for framework communication. Much like PureMVC, Commands can be bound to events.

No parameters are passed to a Command’s execute method however. Instead, you define the concrete event that will be passed to the Command as a dependency. This relieves you from having to cast the event.

Multiple Commands can be bound to an event type. They will be executed in the order that they were mapped. This is very handy for mapping your startup commands.

To get a reference to the concrete event that triggered a Command, you must declare the event as a Dependency:

    public class TryClearMessages extends Command
    {
    	[Inject]
    	public var event:SystemEvent;
      
    	[Inject]
    	public var userProxy:UserProxy;
      
    	[Inject]
    	public var messageProxy:MessageProxy;
      
    	override public function execute():void
    	{
    		if ( userProxy.userLoggedIn )
    		{
    			messageProxy.clearMessages();
    		}
    		else
    		{
    			contextView.addChild( new LoginPage() );
    		}
    	}
    }

Mediators

Robotlegs makes it easy to work with deeply-nested, lazily-instantiated View Components.

You map Mediator classes to View Component classes during startup, or later during runtime, and RobotLegs creates and registers Mediator instances automatically as View Components arrive on the stage (as children of the Context View).

A Mediator is only ready to be interacted with when it’s onRegister method gets called. This is where you should register your listeners.

The default Mediator implementation provides a handy utility method called addEventListenerTo(). You should use this method to register listeners in your Mediator. Doing so allows RobotLegs to automatically remove any listeners when a Mediator gets removed.

A Mediator might look something like this:

    public class HelloFormMediator extends Mediator
    {
    	[Inject]
    	public var helloForm:HelloForm;
      
    	[Inject]
    	public var messageProxy:MessageProxy;
      
    	override public function onRegister():void
    	{
    		// View Listeners
    		addEventListenerTo( helloForm, HelloFormEvent.FORM_SUBMITTED, onFormSubmitted );
    		// Context Listeners
    		addEventListenerTo( eventDispatcher, MessageProxyEvent.MESSAGE_ADDED, whenMessageAdded );
    	}
      
    	private function onFormSubmitted( e:HelloFormEvent ):void
    	{
    		messageProxy.addMessage( helloForm.getMessage() );
    	}
      
    	private function whenMessageAdded( e:MessageProxyEvent ):void
    	{
    		helloForm.messageTxt.setFocus();
    	}
    }

The Mediator above has two dependencies:

  • It’s View Component: HelloForm
  • The MessageProxy

It listens to events from the view, invokes methods on the MessageProxy’s API, and listens to the Context’s event bus for MessageProxyEvent events.

NOTE: addEventListenerTo() is a convenience method. It keeps track of any listeners registered and removes them when the Mediator is removed.

Proxies

Proxies are much like Mediators, but instead of wrapping View Components, they manage access to data (or Models).

Services

Services are like Proxies, but instead of managing Models, they manage access to remote services.

Clone this wiki locally