Mediator can't hear an Event

Timur's Avatar

Timur

22 Jul, 2011 08:08 PM

Hi,

I've put together a small RL project for learning purposes and have come upon a strange road block. Here's what's happening:
I have a context that triggers the StartupCommand through ContextEvent.STARTUP. Check.
The StartupCommand has the getTemplatesService load a dummy service. Check.
When done, the service dispatches a TemplateResultEvent.RECEIVED event with a templates:ArrayCollection payload. Check.
Through a commandMap in the context I have mapped the TemplateResultEvent.RECEIVED event to HandleReceivedTemplatesCommand
HandleReceivedTemplatesCommand runs and updates the templateModel. Check
The TemplateModel's setter triggers the TemplateModelEvent.TEMPLATES_UPDATED event which fires. Check.
In the onRegister function of the SpecsViewMediator, the mediator listens for the TemplateModelEvent.TEMPLATES_UPDATED and has the updateTemplatesDD handler waiting to handle that event. Problem!
The updateTemplatesDD handler never runs.

I tried debugging it, but get nothing useful (probably because the Robotlegs swcs are compiled). Before I use the uncompiled Robotlegs for debugging, can anyone see anything that I'm omitting, or point out the not so obvious?

Thanks,

Tim

Code:

    //CONTEXT
public class TemplateMakerContext extends Context
{
    public function TemplateMakerContext(contextView:DisplayObjectContainer = null, autoStartup:Boolean = true)
    {
        super(contextView, autoStartup);
    }

    override public function startup():void
    {
        injector.mapSingleton(TemplateModel);
        injector.mapSingleton(GetTemplatesService);

        mediatorMap.mapView(SpecsView, SpecsViewMediator);

        commandMap.mapEvent(TemplateResultEvent.RECEIVED, HandleReceivedTemplatesCommand, TemplateResultEvent);
        commandMap.mapEvent(ContextEvent.STARTUP, StartupCommand);

        // startup
        dispatchEvent(new ContextEvent(ContextEvent.STARTUP));
        super.startup();
    }
}

//STARTUP COMMAND
public class StartupCommand extends Command
{
    [Inject] public var getTemplatesService:GetTemplatesService;

    override public function execute():void
    {
        getTemplatesService.load();
    }
}

//SERVICE
public class GetTemplatesService extends Actor
{
    public function load():void
    {
        //stub for now
        onResult([{name:"template_a", id:1}, {name:"template_b", id:2}]);
    }

    private function onResult(results:Array):void
    {
        var e:TemplateResultEvent = new TemplateResultEvent(TemplateResultEvent.RECEIVED);
        e.results = new ArrayCollection(results);
        dispatch(e);
    }
}

//COMMAND
public class HandleReceivedTemplatesCommand extends Command
{
    [Inject] public var templateModel:TemplateModel;
    [Inject] public var templateResultEvent:TemplateResultEvent;

    override public function execute():void
    {
        //update model
        templateModel.templates = templateResultEvent.results;
    }
}

//MODEL
public class TemplateModel extends Actor
{
    protected var _templates:ArrayCollection;

    public function get templates():ArrayCollection;
    {
        return _templates;
    }

    public function set templates(value:ArrayCollection):void
    {
        _templates = value;
        var e:TemplateModelEvent = new TemplateModelEvent(TemplateModelEvent.TEMPLATES_UPDATED);
        e.templates = _templates;
        dispatch(e);
    }
}

//MEDIATOR
public class SpecsViewMediator extends Mediator
{

    [Inject]
    public var specsView:SpecsView;

    [Inject]
    public var templateModel:TemplateModel;


    override public function onRegister():void
    {
        eventMap.mapListener(eventDispatcher, TemplateModelEvent.TEMPLATES_UPDATED, updateTemplatesDD, TemplateModelEvent);
    }


    public function updateTemplatesDD(event:TemplateResultEvent):void
    {
        specsView.template_brand_dd.dataProvider = event.results;
        trace('updated')
    }

}

//VIEW
<s:Panel xmlns:fx="http://ns.adobe.com/mxml/2009"
         xmlns:s="library://ns.adobe.com/flex/spark"
         xmlns:mx="library://ns.adobe.com/flex/mx"
         x="10" y="10" width="250" height="768" backgroundColor="#525252" title="Template View">

    <s:DropDownList id="template_brand_dd" x="10" y="18" width="228" />
</s:Panel>  
//EVENT  
public class TemplateModelEvent extends Event
{
    public static const TEMPLATES_UPDATED:String = "templates_updated";

    public function TemplateModelEvent(type:String, bubbles:Boolean = false, cancelable:Boolean = false)
    {
        super(type, bubbles, cancelable);
    }

    protected var _templates:ArrayCollection;

    override public function clone():Event
    {
        return new TemplateModelEvent(type, bubbles, cancelable);
    }


    public function get templates():ArrayCollection
    {
        return _templates;
    }

    public function set templates(value:ArrayCollection):void
    {
        _templates = value;
    }
}

Showing page 2 out of 2. View the first page

  1. Support Staff 31 Posted by Ondina D.F. on 29 Jul, 2011 07:49 AM

    Ondina D.F.'s Avatar

    Oh, that’s great, Tim! I’ll take a look at it and get back to you later today.
    Ondina

  2. Support Staff 32 Posted by Ondina D.F. on 29 Jul, 2011 05:05 PM

    Ondina D.F.'s Avatar

    That was a lot of work, Tim!! And you were fast!

    I'm not sure whether it's right, and I'm no UML expert (actually, I find it hard to display event driven activity in UML sequence diagrams).

    I'm no UML expert either :) I know it’s not easy to make such a sequence diagram.
    I thought it would be more suited to show the 3 major areas/regions/scopes of an RL-Flex application:

    • RobotlegsInternals as a framework ( Context, MediatorMap, MediatorBase - of interest to us in our example)

    • RobotlegsImplementation (ApplicationContext, Commands, Models, Services and Mediators)

    • FlexComponents (View: ContextView- Application and a SomeView- child component)

    If you think that another type of diagram would be easier to use, or would be more clear, I’d be the last one to complain about it :) Or if you have another tool, that would facilitate the visual representation, go on and use it. Our goal isn’t to present UML best practices, is it?

    I’m not sure which name would be self-explanatory for the 3 areas. RL-Internal, RL-Implementation, Flex-Components... or flex what?
    Let’s say we’ll agree upon a better naming later on, but for now I think it’s important to know, if having only 3 sequence instances/areas/bounderies would be better than having an instance for every class dispatching an event.

    There are some nebulous areas like when AnotherView's creationComplete is triggered by the LayoutManager, but I don't think we need a microscope that powerful. The focus is primarily component and application initialization in Flex and how it relates to RL bootstrapping.

    Exactly, none would benefit from too many details. And we really should try to keep the focus on RL + Flex only.

    I’ll use your diagram to see how it could be simplified and I’ll think about an easier way to represent the flow, while keeping the instances in 3 groups. I will keep you posted about any progress or new ideas, but it will happen slowly. I’m very sorry about that, but
    hopefully my slow steps won’t be a problem for you.

    Thank you for your work and ideas :)

    Ondina

  3. 33 Posted by Timur on 29 Jul, 2011 06:57 PM

    Timur's Avatar

    Hi Ondina,

    I'm no UML expert either :) I know it’s not easy to make such a sequence diagram. I thought it would be more suited to show the 3 major areas/regions/scopes of an RL-

    Flex application:

    • RobotlegsInternals as a framework ( Context, MediatorMap, MediatorBase - of interest to us in our example)

    • RobotlegsImplementation (ApplicationContext, Commands, Models, Services and Mediators)

    • FlexComponents (View: ContextView- Application and a SomeView- child component)

    I agree, I have mixed feelings about UML in general, some of it could be useful, some of it less intuitive. I'm wondering whether a sequence diagram serves this purpose well, or whether it might be better to break this diagram into more manageable chunks, perhaps of different type. I think sequence diagrams start to reach a point of diminishing return once they exceed a certain level of detail. The challenge it seems is to show the three areas you outlined above in a clear manner, while illustrating sequence of Flex framework events, RobotlegsImplementation/Project custom events, and RobotlegsInternals events.

    I’m not sure which name would be self-explanatory for the 3 areas. RL-Internal, RL-Implementation, Flex-Components... or flex what?

    I think that works. Flex-Component is closely related to Flex-Application, since Flex-Application extends a Flex-Component and adds additional functionality. So it could be Flex-Component/Application.

    I think it’s important to know, if having only 3 sequence instances/areas/bounderies would be better than having an instance for every class dispatching an event.

    Do you mean reduce the number of detail?

    I’ll use your diagram to see how it could be simplified and I’ll think about an easier way to represent the flow, while keeping the instances in 3 groups. I will keep you posted about any progress or new ideas, but it will happen slowly. I’m very sorry about that, but hopefully my slow steps won’t be a problem for you.

    I look forward to it. Speed is not a requirement here, only clarity is.

    Thank you for your work and ideas :)

    Thank you for taking the time and creating several illustrative projects that started it all.

    Tim

  4. Support Staff 34 Posted by Ondina D.F. on 30 Jul, 2011 09:49 AM

    Ondina D.F.'s Avatar

    Tim,

    I'm wondering whether a sequence diagram serves this purpose well, or whether it might be better to break this diagram into more manageable chunks, perhaps of different type. I think sequence diagrams start to reach a point of diminishing return once they exceed a certain level of detail. The challenge it seems is to show the three areas you outlined above in a clear manner, while illustrating sequence of Flex framework events, RobotlegsImplementation/Project custom events, and RobotlegsInternals events.

    You are so right! Sequence Diagram is definitively not suited to our needs, or simply because we are no-uml-experts ;) And yes, it might be better to break this diagram into more manageable chunks.

    I think that works. Flex-Component is closely related to Flex-Application, since Flex-Application extends a Flex-Component and adds additional functionality. So it could be Flex-Component/Application.

    Ok, then I’ll go with FlexComponents (Application and ChildComponent) , RobotlegsInternal, RobotlegsImplementation

    Do you mean reduce the number of detail?

    Yep. Less details, more clarity :)

    I’m starting now with a diagram by using only the traces related to the ContextView.
    Till then...

    Ondina

  5. Support Staff 35 Posted by Ondina D.F. on 31 Jul, 2011 11:13 AM

    Ondina D.F.'s Avatar

    Update:

    It's cold and rainy outside, so I spent some time playing with diagrams ;)
    RLStartupSequence_01.png was the first one I made, then RLStartupSequence_02.png and the last one is RLContextViewFlow_01.png
    None of them is complete or nice or clear enough. I also didn’t check if the flow is absolutely correct. I also misused the Sequence Diagram’s elements and so on. Anyway I wanted to let you see them, so you can better understand what I was talking about, when I mentioned the 3 areas of interest. I used Swimlanes(FlexComponents, RLInternal,RLImplementation) and Lifelines(ContextView, ApplicationContext etc)

    RLContextViewFlow_01 shows only the flow for the ContextView + ApplicationMediator + service call. I think we should have more than one diagram. One for the ContextView, one for SomeView and one with both ContextView and SomeView flows, with fewer details than in the first ones. Then we could have variations of the combined flow for the different scenarios (service call on startupcomplete, on applicationcomplete, from onregister of the mediator...) if we want to.

    After taking a closer look at the trace statements, I saw that their order of execution isn’t correct in my code. For example I put trace("[MediatorMap] createMediatorUsing() "+viewComponent+ " "+mediator); in createMediatorUsing after it calls registerMediator(), so registerMediator appears first. I’m sorry for that. My excuse: I made changes to the code in kind of a hurry, between different other tasks and formulating an answer for our discussion.

    So Tim, I hope my ugly diagrams are at least illustrating my point. I’ll try to see if I can reduce the number of details even more without loosing valuable information.

    Ondina

  6. 36 Posted by Timur on 01 Aug, 2011 12:19 AM

    Timur's Avatar

    Hi Ondina,

    I wanted to let you see them, so you can better understand what I was talking about, when I mentioned the 3 areas of interest. I used Swimlanes (FlexComponents, RLInternal,RLImplementation) and Lifelines (ContextView, ApplicationContext etc)

    I think the Swimlanes idea is brilliant. I'm poring over the ContextView Flow now. I like how you have color coded different areas and have assigned different shapes to events, etc. Here are my thoughts/questions/suggestions:

    • Do you think it would make sense to somehow differentiate the ContextEvent.STARTUP chevron visually? I'm thinking that the other events are triggered by either Flex Components or by RL Internals, whereas ContextEvent.STARTUP is a rather arbitrary event and could be confused in this diagram for a "system" level event.

    • Would it be slightly less confusing, do you think, to lower the ContextEvent.STARTUP chevron so that it would not be parallel (on the same Lifeline) with the mapInjections in the rightmost swimlane? I don't think they are related, but being parallel in the diagram makes you associate them. I've attached a small mockup of what I mean.

    • Another question I have is related to the MapView.registerMediator()->MediatorBase.preRegister()->MediatorBase.onRegister() where ApplicationMediator.onRegister()->super() would call the same MediatorBase.onRegister(). It's not yet clear to me how this works since visually the linear continuity is interrupted.

    • Should we show the SomeModelEvent.DATA_UPDATED chevron for completeness' sake, or do you think it's unnecessary?

    • In my version of Startup_Takethree project, I have MapViewsCommand dispatch ContextEvent.STARTUP_COMPLETE that really does nothing. It is the onApplicationComplete handler that triggers the SomeServiceRequest. I mention this because you have a commented out line of code:

      //commandMap.mapEvent(ContextEvent.STARTUP, SomeServiceRequestCommand, ContextEvent, true); //won't work

    And I'm wondering whether we are showing a flow that won't work.

    • And lastly, do you think SomeModel.setData() belongs in the Flex Components swimlane? It's tough to place the model here.

    That's all I can think of for now on the ContextView Flow. Thanks again, Ondina, for doing an excellent job of it. I will now look over the other two diagrams.

    Tim

  7. Support Staff 37 Posted by Ondina D.F. on 01 Aug, 2011 01:32 PM

    Ondina D.F.'s Avatar

    Hi Tim,

    I’ll open a new thread under [Examples], because I think that our current discussion is a little outside the scope of this thread. Your initial question has been answered.

    Our goal now is to find the best way to explain the start-up process in a Flex-RL application through:

    • code

    • diagrams

    • explanations

    I wasn’t sure where to put it. What category does it belong to? It’s not a solution yet, it’s not a problem or question, so I decided to put it under [Examples], because we will have one sooner or later. I also don’t know what would be the most descriptive title for the new thread. I’ll name it “Tracking the Start-up Process of a Flex-RL application” for now. I can change it later into something better(your suggestion?).
    http://knowledge.robotlegs.org/discussions/examples/12-tracking-the...

    See you there :)

    Ondina

  8. Ondina D.F. closed this discussion on 01 Nov, 2011 11:37 AM.

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