Command not firing on custom event

Riaan Cornelius's Avatar

Riaan Cornelius

26 Feb, 2013 01:00 PM

I'm new to Robotlegs and I'm sure I'm doing something stupid, but I just can't see it.

I created a Context which (amongst other things) maps a command:

public class TestContext extends Context implements IContext 
    {
        override public function startup():void
        {
            //map controller
            commandMap.mapEvent(ShowLabelEvent.SHOW, ShowApplicationLabelCommand, ShowLabelEvent);

        //map model
        var labelData:LabelData = new LabelData("init");
        injector.mapValue(ILabelData, labelData);
        injector.injectInto(labelData);

        //map view
        mediatorMap.mapView(TestApp, TestAppMediator);
    }
}</code>



I know the Context is loaded because I can see the trace from the mediator in there's onRegister() method.

For my command, I have:

public class ShowApplicationLabelCommand extends Command
    {
        [Inject]
        public var labelData:ILabelData;

    [Inject]
    public var event:ShowLabelEvent;

    override public function execute():void
    {
        trace(&quot;Executing ShowApplicationLabelCommand with injected event: &quot;+event.type);
        labelData.text = &quot;Text set from Command&quot;;
        labelData.visible = true;
        dispatch(new UiUpdatedEvent());
    }
}</code>



Then in my main Application class, I have a button with this click handler:

private function buttonClick():void {
                trace("Dispatching event from button click:  "+ShowLabelEvent.SHOW);
                dispatchEvent(new ShowLabelEvent());
            }

If I add an eventListener on creationComplete of the Application, I can see that the following event is definately dispatched:

package co.trudon.test.model.events
{
    import flash.events.Event;

public class ShowLabelEvent extends Event
{
    public static const SHOW:String = &quot;ShowLabel&quot;;

    public function ShowLabelEvent()
    {
        super(SHOW, false);
    }

    override public function clone():Event
    {
        return new ShowLabelEvent();
    }
}



}

However, I never see the trace in my command's execute() method. I've been going around in circles for a few hours and I just can't figure it out.

Any ideas?

  1. Support Staff 1 Posted by Ondina D.F. on 26 Feb, 2013 02:51 PM

    Ondina D.F.'s Avatar

    Hi Riaan,

    There are several things that need improvement in your code. I’ll try to address just some of them now, and depending on your questions I’ll say more later.

    The way you’re dispatching the event from your view is one of your problems. The command never gets triggered.
    In your view, instead of

    dispatchEvent(new ShowLabelEvent());
    

    you need to dispatch it like this:

    dispatchEvent(new ShowLabelEvent(ShowLabelEvent.SHOW));
    

    And in your mediator’s onRegister:

    addViewListener(ShowLabelEvent.SHOW, dispatch, ShowLabelEvent);
    

    You need a Mediator to relay view’s events to the rest of your application, on the shared event dispatcher.

    Your event class looks like this:

    public class ShowLabelEvent extends Event
        {
            public static const SHOW:String = "ShowLabel";
            
            public function ShowLabelEvent ()
            {
                super(SHOW, false);
            }
            
            override public function clone():Event
            {
                return new ShowLabelEvent();
            }
        }
    

    I’d do it like this:

    public class ShowLabelEvent extends Event
        {
            public static const SHOW:String = "ShowLabel";
            
            public function ShowLabelEvent(type:String,  bubbles:Boolean=false, cancelable:Boolean=false)
            {
                super(type, bubbles, cancelable);
            }
            
            override public function clone():Event
            {
                return new ShowLabelEvent(type);
            }
        }
    

    Another problem: You’re trying to inject a Model into the View. View injection isn’t supported in rl1. There are workarounds to achieve this, but first of all injecting the Model into the View is not a recommended practice, if you want to follow the MVCS pattern.
    What you should do, is either let your command dispatch an event with the labelData or a VO as a payload

    dispatch(new UiUpdatedEvent(UiUpdatedEvent.UPDATED, labelData.text));
    

    or let your model dispatch the above event after setting the new data.

    And then in your mediator

    public function showTestAlert(event:UiUpdatedEvent):void
    {
       Alert.show("Event caught by test mediator");
       view.someLabel.text=event.payload;
    }
    

    It’s a common practice to use VOs (value objects) to transport data between app’s layers.

    You might want to read the best practices and try out a few examples. Tell me if you don’t know where to find them, and of course don't hesitate to ask more questions, if you need more clarifications.

    Ondina

  2. 2 Posted by Riaan on 26 Feb, 2013 07:46 PM

    Riaan's Avatar

    Thanks Ondina,

    My main issue was understanding that I had to relay the event from the view to the shared event dispatcher and how to get the data back to the view.

    I see it working on my test app with these changes and I think I have a much better idea of how to do things now. I'll try it on my real application tomorrow and let you know if I have any more questions.

  3. Support Staff 3 Posted by Shaun Smith on 27 Feb, 2013 10:16 PM

    Shaun Smith's Avatar

    Hello, I'm closing this thread for now. Please feel free to re-open it if you are still experiencing issues.

  4. Shaun Smith closed this discussion on 27 Feb, 2013 10:16 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