First, a little backstory on how I got to this error in the first place (bear with me). I recently start a project using Robotlegs 2.0.0. Since this version was just released, a lot of the extensions are still being ported over. In my case, I had need of the RelaxedEventMap extension, which I had used heavily with RL1. Thankfully, CReynders was kind enough to port the existing RL1 source over to an RL2 extension; however, porting the extension also required a few minor tweaks to the RL framework source. What this meant to me is that if I wanted to use the RelaxedEventMap extension, I would need to download the latest Robotlegs source from GitHub which contained the previously mentioned tweaks (i.e. I could no longer use the latest compiled version of the RL2 SWC). I didn’t assume this would be a big deal, that is, until I tried to compile my application using Flash Pro. The compile-time went from about 2 seconds using the compiled RL2 SWC, to upwards of 30 seconds when including the RL2 framework source. All this led me down the path of compiling the RL2 SWC myself for the first time (see, I told you’d I’d get to the point eventually!).
I recently gave a presentation at the San Diego Flash Users Group (SDFUG) about getting started with the Robotlegs framework. Below are links to the source files for the example application (TweetBender) that I discussed, as well as some useful links for getting started with Robotlegs.
- TweetBender source
- Robotlegs Knowledgebase
- Robotlegs Best Practices
- Robotlegs “Gotcha’s” and other useful tips on Geekgonenomad
- Introduction tutorial on Robotlegs from InisdeRIA
I ran into an issue today where I was receiving multiple events from a single view component. I did a little digging and quickly discovered it was due to the fact that my view mediator was using the RelaxedEventMap and I was not performing any sort of cleanup routine to unregister the listeners of the eventmap. The key piece of information to understand when using the RelaxedEventMap is that there is only ONE eventmap shared across all of your mediators (unlike the normal eventmap which each mediator has an individual copy of). The result of this is that if you do not properly clean up after yourself (i.e. removing listeners to the RelaxedEventMap from your mediators upon removal), then the listeners will still exist and will continue to pickup events even after the view has been removed. Continue Reading
The problem: You’ve created a custom event which has some custom properties (say an array of data you’d like to pass along), and are dispatching it via the Robotlegs context. You create your new event, populate your data property, and send it on its’ way via the dispatch method:
var e:MyCustomEvent = new MyCustomEvent( MyCustomEvent.SEND_DATA );
e.data = myArray; // or some other data you want to pass along
trace("My array is an array = " + (myArray is Array) ); // returns true
dispatch( e );
The event dispatches nicely; however, when it is received (by a command, or listening mediator), the data property is null!
// Code snippet from command mapped to this MyCustomEvent.SEND_DATA
public var event:MyCustomEvent;
public override function execute():void
trace("My events' data is an array = " + (event.data is Array) ); // returns false!!!
While implementing the Robotlegs framework into my first application, I came across a rather common issue: How do I properly manage my views? To give you the basic run-down, my application has a number of different views (menus and various other screens) that need to be shown on the display at different times throughout the application lifecycle. What I wanted was a way to store all of my views, and be able to map events to show a specific view at a given time (ex: a user clicks the logout button in some component, I want the login menu to be shown). Add to this situation the fact dependency injection (while wonderful) has one pretty major flaw: If the object that needs to listen for a particular event is created after the event is dispatched, you end up with a race condition, and the object usually loses (and as such could be shown in an invalid state). For the example of the login menu, let’s say that the use clicks the logout button, the event is fired to trigger a logout command, which then tells the application to display the login menu. This is all well and good unless there is some event that the login menu needs to listen for that gets fired before it is created (ex: The logout Command fires an event to tell the app that the user has logged out and this event contains a message “The users has been logged out successfully” that the login menu is supposed to display). If you’re still managing to follow my confusing-ass example, give yourself a high five!
THE SOLUTION: Continue Reading
One of the common practices suggested by the Robotlegs team (and one I have personally grown to love) is the user of Interfaces for your services and data models. What this allows you to do is type-cast all of your injections and other references to these classes using the name of the Interface, then, when mapping these classes, you map the Interace to the either the concrete class or a seperate “mock” class that can be used for testing. This gives you the ability to quickly swap between mock data and live data by simply changing the injection mappings in your context file (or startup command or wherever you handle your mappings).
I ran into some issues today trying to get my first Robotlegs based application to run. I was using Flash Professional as my publishing tool and Flash Builder 4 as my code editor, and for some reason whenever I tried to publish the compiler would bark about a null object reference whenever I tried to access one of my views. After a bit of digging I stumbled across a blog post stating that you have to check the “Export swc” option in the Flash Professional publish settings when building a Robotolegs project using flash. After updating my publish settings everything worked perfectly. This has something to do with the compiler stripping out the [Inject] metadata when publishing the .swf.