A mediator cannot listen to an event dispatched by another mediator.

edeventner's Avatar

edeventner

03 Oct, 2011 08:11 AM

How do I make my event that is dispatched by a mediator being listened to another mediator? I cannot find the solution in this site because it only talks about models and services event listening/dispatching, no mediator to mediators.

Or is there another way for this? Here's what I want to achieve:
When a timer is done (that is part of my mediator), I want to load a window that is going to load a module. Now that the timer is done, I cannot load my window component because it would need another mediator to communicate to this window component. So what I did is, I dispatched a custom event when the timer is done and also I created a mediator for the window component then have this new mediator listen to the dispatched custom event. Yet, cannot achieve listening to this event.

Sorry as I am new to Robotlegs. Thanks

  1. 1 Posted by krasimir on 03 Oct, 2011 08:18 AM

    krasimir's Avatar

    Hello,

    Robotlegs has a really nice eventDispatcher which is available in every mediator. For example in your first Mediator:
    eventDispatcher.dispatch(new YourCustomEvent(YourCustomEvent.EVENT))

    in your second Mediator:
    eventDispatcher.addEventListener(YourCustomEvent.EVENT, handler)

    I strongly recommend to read more about eventMap.

  2. 2 Posted by edeventner on 03 Oct, 2011 08:25 AM

    edeventner's Avatar

    @krasimir, thanks for the quick reply. I was about to say "gotcha!" reading your solution but when I tried it, doesn't work as well.

    Here's my code in my first mediator:
    dispatch(new LoginEvent(LoginEvent.STARTUP));

    second mediator:
    eventMap.mapListener(eventDispatcher, LoginEvent.STARTUP, loadLoginModule);

  3. 3 Posted by krasimir on 03 Oct, 2011 08:29 AM

    krasimir's Avatar

    Hm ... strange. There are several reasons to not work:
    1. You missed to map your mediator to your view (which means that the onRegister method is never called) by using mediatorMap.
    2. The dispatching of the event is called when the view for the second mediator is not added to the stage. Which means that the onRegister method is called later and the listener is added after the dispatching.

  4. 4 Posted by edeventner on 03 Oct, 2011 08:40 AM

    edeventner's Avatar

    I guess #2 is my case here. The first mediator is actually the mediator of my main application and the second mediator is for the window component to be loaded.

    But in my Context, this is the order of mapping my mediators:
    mediatorMap.mapView(LoginWindow, LoginWindowMediator);
    mediatorMap.mapView(OptionsSoftware, MainViewMediator);

    So how may I able to check in my application that all these mediators are done being mapped? So when the timer is done, I'll check for it first before dispatching the event on my main application.

    Thanks

  5. 5 Posted by krasimir on 03 Oct, 2011 08:47 AM

    krasimir's Avatar

    Basically you should give us more information about the logic of your application. As far as I can see the problem is more like a conceptual rather then technical. Isn't it possible to map your LoginEvent.STARTUP to a command which actually shows your window.

    From my point of view you are trying to show a view from itself. I.e. sounds like trying to add the view/window to the stage from the mediator of that view. Which, by my opinion, is not really the correct flow.

  6. 6 Posted by edeventner on 03 Oct, 2011 09:17 AM

    edeventner's Avatar

    Thanks krasimir. I just realized that only my main app mediator gets the onRegister method fired and the rest is not being registered. I put a trace statement on each onRegister methods but only my main app mediator provided the output yet I have them registered correctly on my Context. :(

    I've read articles here on the issue of their mediator not firing the onRegister also and I've read one of your comments that the issue was the view wasn't added on stage before the event was dispatched. But how may I able to achieve this to my case since the components aren't supposed to be loaded on stage because they have to wait for a module loader to load them?

    Thanks

  7. 7 Posted by krasimir on 03 Oct, 2011 09:27 AM

    krasimir's Avatar

    For me, it looks like a good idea to map your event to a command. I.e.:
    - map your event to a command - dispatch your event when the time does its job - the command is executed and you know that you have to add/load a specific view to the stage - add your view If you use this flow the logic which will add the view to the stage is outside the mediator. I like to think that the mediators are objects which operates with the views when the views are added on the stage.
    If that still not work for you, can you please give us a little bit more information on what exactly you are trying to achieve.

  8. 8 Posted by edeventner on 03 Oct, 2011 10:34 AM

    edeventner's Avatar

    Yes, thank you krasimir. That makes a lot of sense. I should use a command to do the job of loading a component to stage so that I can then have its mediator working. And thanks about the way of thinking what a mediator is. That gives me light to how this framework really works.

    However, on trying to achieve the goal by using a commandMap on a Context,
    commandMap.mapEvent(LoginEvent.STARTUP, OpenLoginWindowCommand, LoginEvent, true);

    ... I got the following error: Error: Injector is missing a rule to handle injection into target [object OpenLoginWindowCommand]. Target dependency: modules.login::LoginWindow

    What does that 'missing' mean? I did the [Inject] on my command class:
    [Inject] public var loginWindow:LoginWindow;

  9. 9 Posted by krasimir on 03 Oct, 2011 10:38 AM

    krasimir's Avatar

    I'm glad that I helped.
    How and where did you map the LoginWindow class? Did you use injector in your context or ...

  10. 10 Posted by edeventner on 03 Oct, 2011 11:01 AM

    edeventner's Avatar

    Well, your question really rings a bell but I can't yet figure out exactly what made the bell rang and how to see the light for I'm really new to Robotlegs.

    Ok, so these are the the lines inside my startup on context:

    mediatorMap.mapView(LoginWindow, LoginWindowMediator);
    mediatorMap.mapView(Main, MainViewMediator);
    commandMap.mapEvent(LoginEvent.STARTUP, OpenLoginWindowCommand, LoginEvent, true);

    .. and no, I haven't used any injectors in my context.

    The error is gone when I tried removing the [Inject] metadata inside my command class and it did open my new window component however its mediator didn't fire up the onRegister method since my trace statement inside it wasn't displaying an output. Is it maybe because of the "new" keyword inside the execute method that confuses the mapping?

    loginWindow = new LoginWindow(); // removing this line will throw an error on the next line.
    loginWindow.open();

  11. 11 Posted by krasimir on 03 Oct, 2011 11:20 AM

    krasimir's Avatar

    If you want to use the [Inject] tag you should map what you want to inject before that. I.e. Robotlegs is telling you that you are trying to inject something that the framework is not informed for. To make the things work with the inject tag, i.e.
    [Inject] public var loginWindow:LoginWindow; You should add this in your context for example:
    injector.mapClass(LoginWindow)
    Then when you use [Inject] the framework will populate your variable with an instance of LoginWindow. I.e. there is no need to use "new LoginWindow" if your injection works.

    I'm not sure that you need injection In your case. My advice is to leave the flow without [Inject] tag, i.e. like you wrote it above loginWindow = new LoginWindow();
    The onRegister method is called if the loginWindow is added on the stage. So, you should check what is going on when you call .open() method and is the LoginWindow instance actually added.

    P.S.
    I strongly recommend http://www.amazon.com/ActionScript-Developers-Guide-Robotlegs-Hooks...
    It covers everything about Robotlegs ;)

  12. 12 Posted by edeventner on 03 Oct, 2011 12:37 PM

    edeventner's Avatar

    I didn't know there is really an "injector" exist aside from the [Inject]. Your suggestion does give me now the idea as to why the bell rang earlier from my comment. When I added "injector.mapSingleton(LoginWindow);" to the context, it successfully injected the login window to my command class and does not throw an error whether I use "new LoginWindow()" or not.

    But the problem is the onRegister still doesn't fire up. Then I reflected on this,
    "The onRegister method is called if the loginWindow is added on the stage." and realized to ask the question whether loading a window really adds the window to the stage of the app that is calling? Since the native window has its own stage, I think that is why the onRegister does not fire up since it isn't being loaded to the original stage.

    My bad, this issue isn't a Robotleg issue but rather a Flex issue. I guess I'll open a discussion for this issue at the Flex forum than here.

    I learned a lot from your comments krasimir :) Thanks so much for the time. I'm happy to choose Robotlegs over the others as to its simplicity, lightweight-ness and great community support. And thanks for the book recommendation. I'm excited to have a copy of it since it is still fresh - published this year. :)

  13. 13 Posted by edeventner on 03 Oct, 2011 12:42 PM

    edeventner's Avatar

    Or, does this mean I have to use another context in this case - for the new window? Is it possible to have more than one context in an application? Since I'll be using lots of windows in this air project and will be a modular approach.

  14. 14 Posted by edeventner on 03 Oct, 2011 12:55 PM

    edeventner's Avatar

    Wow! Haha I'm grateful to Robotleg's great community support. :) It solved my problem now from here: http://knowledge.robotlegs.org/kb/reference-mvcs-implementation/how...

    Flex pop-ups and opening new windows works similarly. I applied the solution from that post and my loginWindowMediator now firing up the onRegister method :)

    I'll mark this as resolved.

    Big thanks,
    -Ed

  15. edeventner closed this discussion on 03 Oct, 2011 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