Mediator dispatches on mapListner to view but not on elements within the view

actimel76's Avatar

actimel76

15 Mar, 2012 03:55 PM

Hi,

I got a little problem and am not sure why. Forgive me I'm new to Robotlegs

In my view I have various buttons which I pick up on via FLAmcUserInterface.<instance name>.
In my mediator for this view I first inject the view and the signal I wish to use then add the following code:

eventMap.mapListener(view, MouseEvent.CLICK, clickTestHandler, MouseEvent);

Which runs:

private function clickTestHandler(e:MouseEvent):void { trace("CLICK = " + e.target.name); }

This runs every time (it traces out), now if I try to map a listener directly to an element on the view eg:

eventMap.mapListener(view.FLAbtnMainMenuOption1, MouseEvent.CLICK, clickTestHandler, MouseEvent);

I get no errors but also nothing gets run???

I trace out the view.FLAbtnMainMenuOption1 its not null and I've tried setting this as a SimpleButton and as a MovieClip setup as a button with the same result.

Any ideas? Me baffled.

  1. Support Staff 1 Posted by Joel Hooks on 15 Mar, 2012 04:05 PM

    Joel Hooks's Avatar

    I recommend never listening to sub-objects. Have the view manage its subobject events and relay them to the mediator accordingly. I also recommend not using generic events like a MouseEvent, opting for custom events that are specific to your problem domain.

  2. 2 Posted by Stray on 15 Mar, 2012 04:19 PM

    Stray's Avatar

    +1 for almost-never listening to sub objects (too many race condition / replacement of child issues).

    I like signals for view-> mediator coms too.

  3. 3 Posted by actimel76 on 15 Mar, 2012 04:21 PM

    actimel76's Avatar

    hmm ok...

    So in my view I would apply standard addEventListeners to each of my menu buttons and each of the mouseEventHandling functions I would then?

    How would I link to the mediator?

    At a guess, would I place dispatchEvent( new MouseEvent(MouseEvent.CLICK) ); in to each of the views mouseEventHandling functions and then in the mediator make listeners which listen to the view for these events and then fire the signals via signalClassName.dispatch(e.target.name);

    I'm trying to work out how to use signals. trying lol

    Also how does one listen to a signal, eg I would like to only start my application once my model has loaded some xml. I've not quite got to this part yet but any info you could supply would be much appreciated. :)

  4. 4 Posted by Stray on 15 Mar, 2012 04:33 PM

    Stray's Avatar

    Hi there,

    you can make the signals unique and meaningful, and they would be properties of the view.

    So - taking the example of a log in panel that has 2 fields and 2 buttons (submit and cancel)

    In the view you have:

    public function get submitted():Signal
    {
    // the ||= operator is just for lazy instantiation
    return _submitted ||= new Signal(String, String);
    }

    public function get cancelled():Signal
    {
    return _cancelled ||= new Signal();
    }

    The actual handlers on the individual buttons would simply need:

    cancelButton.addEventListener(MouseEvent.CLICK, cancelClickedHandler);
    submitButton.addEventListener(MouseEvent.CLICK, submitClickedHandler);

    private function cancelClickedHandler(e:MouseEvent):void
    {
    cancelled.dispatch();
    }

    private function submitClickedHandler(e:MouseEvent):void
    {
    submitted.dispatch(username.text, password.text);
    }

    In the (SignalMediator) mediator you'd have:

    override public function onRegister():void
    {
    addToSignal(view.submitted, handleSubmit);
    addToSignal(view.cancelled, handleCancel);
    }

    protected function handleSubmit(username:String, password:String):void
    {
    dispatch( new AccountLoginEvent(AccountLoginEvent.LOGIN_REQUESTED, username, password) );
    }

    etc

    hth,

    Stray

  5. 5 Posted by actimel76 on 15 Mar, 2012 07:26 PM

    actimel76's Avatar

    But in my case of having 6 buttons which change page content if I handle wth a single signal in the view which passes the string of which page to go to would be better than having 6 signals? MenuSignal(String)

    Also if I do it that way wouldn't I it make more sense then to just bypass the views mediator and let the root mediator handle the change of content as there would be nothing for the views mediator to do and if we do bounce the command again in the views mediator isnt that just extra work for no reason?

    Here's what I got.... So it's flow is:

    root context > startup > view (stage view) > stage mediator (potentially skip?) > root context mapped signal > command to take injected views and update depending on which section name is given.

    I know this ia s lot to look at... Is that correct?

    rootContext.as
    // # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
    // Map the model singletons injector.mapSingleton(ConfigModel);
    injector.mapSingleton(HomePageModel);
    injector.mapSingleton(LanguageModel);
    injector.mapSingleton(MainMenuModel);
    injector.mapSingleton(MainMenuPopupsModel);
    injector.mapSingleton(NavigationModel);
    injector.mapSingleton(PagesModel);
    injector.mapSingleton(QuickMenuModel);
    injector.mapSingleton(RemoteControlModel);

    // TODO: Need to popuplate the models with xml data before app run

    // map the signals injector.mapSingleton(UpdateDisplaySignal);

    // Add to stage sequence var stageView:StageView = new StageView();
    contextView.addChild(stageView);

    // map the views to their mediators mediatorMap.mapView(StageView, StageMediator);

    //map events - startup complete commandMap.mapEvent(ContextEvent.STARTUP_COMPLETE, StartUpCommand);

    // A startup signal is created in order to call the StartupCommand var startupSignal:Signal = new Signal();
    signalCommandMap.mapSignal(startupSignal, StartUpCommand);
    startupSignal.dispatch();

    StartUpCommand.as - is empty
    // # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

    UserInterfaceMediator.as
    // # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
    override public function onRegister():void
    {

    trace("StageMediator.onRegister()");
    
    view.init();
    

    }

    UserInterfarceView.as
    // # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
    private var mcUserInterface:FLAmcUserInterface;
    private var menu:MovieClip;

    private var mainMenu:MainMenu;
    private var menuSelectionSignal:Signal;

    public function StageView(){ trace("StageView()"); }

    public function init():void
    {

    trace("StageView.init()");
    
    // Setup main UI asset
    mcUserInterface = new FLAmcUserInterface();
    addChild(mcUserInterface);
    
    // Clear container contents (it has a locator shape in it from the FLA visual positioning)
    mcUserInterface.FLAmcVirtualWorldContainer.graphics.clear();
    new RemoveAllChildrenIn(mcUserInterface.FLAmcVirtualWorldContainer);
    
    // Map menu and menu options
    mainMenu = new MainMenu(mcUserInterface);
    mainMenu.x = 465; mainMenu.y = 26;
    //new DebugPosition2D(Variables.stage,mainMenu);
    addChild(mainMenu);
    
    // Define menu selection signal
    // String will be which menu option has been selected for root context to work out what to fade in & out (instead of having 6 signals)
    menuSelectionSignal = new Signal(String);
    
    // Define names & listeners
    mainMenu.menuOptionResources.addEventListener(MouseEvent.CLICK,clickHandler);
    mainMenu.menuOptionWhitePapers.addEventListener(MouseEvent.CLICK,clickHandler);
    mainMenu.menuOptionCaseStudies.addEventListener(MouseEvent.CLICK,clickHandler);
    mainMenu.menuOptionContactUs.addEventListener(MouseEvent.CLICK,clickHandler);
    mainMenu.menuOptionShare.addEventListener(MouseEvent.CLICK,clickHandler);
    

    }

    private function clickHandler(e:MouseEvent):void
    {

    trace("StageView.clickHandler(): name = " + e.target.name);
    
    // Get targets name for signal to process the targets name
    var clickedName:String = e.target.name;
    menuSelectionSignal.dispatch(clickedName);
    

    }

  6. 6 Posted by Jerome Maurey-D... on 17 Apr, 2012 01:08 AM

    Jerome Maurey-Delaunay's Avatar

    The mediator's job is to relay info to and from the view. So, although it may seem like a short cut to have a "root" mediator that handles it all, you will eventually create dependancies that will limit your code re-use and will end up with spaghetti code, which defeats the purpose of using MVC.

    The extra time spent de-coupling your app will save you countless hours debugging intertwined code. If each actor has clearly defined tasks, when something breaks you can isolate the culprit easily :)

    Cheers,

    J.

  7. Ondina D.F. closed this discussion on 22 Jun, 2012 07:36 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