Capture event in Mediator from Sprite in View Component

seanlail's Avatar

seanlail

17 Dec, 2009 05:27 PM

I'm just getting in to RobotLegs (awesome, by the way) from Cairngorm (not awesome...).
Loving it. Not having to make a million casts everywhere is sexy.

Anyways, to get comfortable with RL I've been converting some old projects.
I'm just stuck at the moment... I'm trying to capture an event in a handler in a Mediator (or to execute a Command) from an instance that does not extend anything from RobotLegs.

The app is a simple little gallery.
I have a ThumbsView, which is mapped to a ThumbsViewMediator.
When the Mediator registers, it uses values in the model to figure out how many "Thumbs" to add to the view component.
"Thumbs" is a simple class that extends Sprite, when it's added to the stage it adds a listener for CLICK events. In the CLICK event handler, I'm dispatching a native flash event.

In my context, I have mapped a Command to this event.
The Command updates the model based on which Thumb was clicked and then calls a method on an ImageViewMediator to update the selected (large) image.

This works fine, if I dispatch the event from a Mediator (inital start up, so that the first image is shown).
However, when I dispatch the event from within the "Thumbs" class, it's not heard.

I'm obviously missing something.

I've tried bubbling the event up, but it will just bubble to the Main class.
I guess I need it to bubble up to where the Context event dispatcher is?
How do I handle this?

My inital thought was to map a listener to the view from the mediator like so:
In ThumbsViewMediator:
eventMap.mapListener( viewComponent, ThumbEvent.THUMB_CLICKED, handler );

Then have the listener in the Mediator dispatch the event... but that doesn't work?

What am I missing?

This is a pure AS3 project, compiled with MXMLC, if that makes a difference.

  1. Support Staff 1 Posted by Joel Hooks on 17 Dec, 2009 05:39 PM

    Joel Hooks's Avatar

    Possibly the easiest way to accomplish this is to add a mediator to the Thumb class. now, as these are added to the stage, they have their own mediators. Now, in that mediator, listen to the CLICK event from the thumb.

    if the event is bubbling up to the ThumbsView, you can listen for the event via its mediator as well.

    If you want to break the project down a bit and post code, I can be more specific.

  2. 2 Posted by seanlail on 17 Dec, 2009 08:23 PM

    seanlail's Avatar

    Hi Joel,

    Thanks for the reply.

    I've attached are the files (remove branding and replaced images with dummy ones).

    I tried as you suggested and created a mediator for just the "Thumb" class.
    This didn't work though and I've reverted it back to the normal event getting dispatched and the ThumbsViewMediator listening to the view component for the event.

    All the classes that are in the "lib" package dispatch an event and aren't being listened to.

    I think I'm just not using the framework correctly :P
    Any advice on how to restructure this would be greatly appreciated.

  3. Support Staff 3 Posted by Shaun Smith on 17 Dec, 2009 10:09 PM

    Shaun Smith's Avatar

    Hi Sean,

    I've just had a quick look through your project, and a couple of things stand out:

    1: In Main.as, you need to hold on to the MainContext object - otherwise it will be free for garbage collection. Simply assign it to a property when you instantiate it.

    2: Commands, in Robotlegs, are short-live, stateless objects - they are not designed to handle asynchronous operations. After the execute method has completed, nothing holds on to the command instance, and it will be free for garbage collection.

    Async operations (like those in your LoadBitmapsCommand and LoadXMLCommand) should happen in Services. To create a Service simply extend Actor and use mapSingleton() in your context. Then inject the Service wherever you need it.

    One you have moved the code into Services you might find that some of your commands now simply call a method on a Service - which is often unnecessary. Instead, you can just call the Service's load() method directly from a Mediator (or elsewhere), and remove the associated command mappings.

    3: Your original issue: You are dispatching non-bubbling events from the thumbs themselves, but then listening to the container. You will need to enable bubbling if you want to listen in that fashion - ln 21 of ThumbEvent: super( type, true );

    4: Robotlegs has a ready-made mechanism for waiting for the context view to arrive on stage. You could remove most of the code from Main.as and perform that stuff in the startup() hook or in a Command - without needing to wire your own ADDED_TO_STAGE listener - as startup() will only run when the context view lands on stage in any case.

    Hope that helps!

  4. 4 Posted by seanlail on 18 Dec, 2009 05:28 PM

    seanlail's Avatar

    Hey Shaun, nice one!
    All sorted, the whole thing is a lot cleaner.

    I originally had the commands just calling a service but didn't like that extra step hence all in the command. Much cleaner to do it from the Mediator though.

    Thanks for the advice and have a great weekend.

    Let's dop!

    (attached revised code for future reference)

  5. Till Schneidereit closed this discussion on 02 Mar, 2010 12:55 PM.

Comments are currently closed for this discussion. You can start a new one.

Keyboard shortcuts

Generic

? Show this help
ESC Blurs the current field

Comment Form

r Focus the comment reply box
^ + ↩ Submit the comment

You can use Command ⌘ instead of Control ^ on Mac