PureMVC Architects Lounge

Announcements and General Discussion => General Discussion => Topic started by: Vander on May 16, 2008, 01:37:01

Title: 1 mediator 2 views
Post by: Vander on May 16, 2008, 01:37:01
how to register more than one view with same mediator?

Title: Re: 1 mediator 2 views
Post by: puremvc on May 16, 2008, 05:43:02
The Mediator only has one view component property, vbut it can manage children of that component if the view component so exposes them.


Title: Re: 1 mediator 2 views
Post by: Vander on May 17, 2008, 10:37:01
aaaaaa.. ive tried all i cannot dispatch :(

<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml">

<mx:Script> <![CDATA[
//public static const TERMINOU_SPLASH:String = "terminouSplash";
import com.empresa.Teste.ApplicationFacade;
import flash.events.Event;

private function inicia():void
// dispatchEvent( new Event( TERMINOU_SPLASH ));
// parent.dispatchEvent( new Event( ApplicationFacade.SHOW_LOGIN, true ));
// dispatchEvent( new Event( ApplicationFacade.SHOW_LOGIN, true ));
]]> </mx:Script>
<mx:Image creationComplete="inicia()"/>

ive tried using event meta too
but i simply cannot catch the event in the applicationmediator :(
with addeventlistener

on my first application screen mxml. (registered on start with applicationmediator.as)
i have a viewstack
the first item is the splashscreen
the second one, a loginform

its like a model that i have to make applications or sites
because if it not uses loginform... it can use another thing
so the splashscreen is the first one automatically registered
when thinking about the deferred instatiation management, done in the applicationmedatior.
i just dont want to use a mediator for splashscreen... :( becuase would be just to dispatch a single event... :(

thanks... its the last thing before i can start to work.. :)

Title: Re: 1 mediator 2 views
Post by: puremvc on May 18, 2008, 07:19:29
ive tried using event meta toobut i simply cannot catch the event in the applicationmediator

When you dispatch an event and want to listen for somewhere farther up the display hierarchy,
you have to set the event to bubble. Otherwise only the immediate parent of the dispatching object gets a chance to handle it.


Title: Re: 1 mediator 2 views
Post by: Vander on May 18, 2008, 09:40:18
Thanks, but can you give me an example, how to achieve something like this? :(
sorry disturbing...

Title: Re: 1 mediator 2 views
Post by: puremvc on May 18, 2008, 12:02:58
Ok. Lets imagine that you have an application that manages important lists.

You have a custom ListsNavigator class extending TabNavigator with a corresponding ListsMediator.

ListsNavigator instantiates two children, both custom components extending Panel, called StuffPanel and ThingsPanel.

The ListsMediator will:

1. Respond to SHOW_STUFF and SHOW_THINGS Notifications by selecting the appropriate child in the ListsNavigator - the immediate viewComponent of this Mediator.

2. Wait until onRegister before setting event listeners or sending notifications. A recently recognised best practice: With the advent of onRegister, we can be sure that we are connected to the framework before performing any operations that could result in notifications being sent or received.

3. In onRegister, set event listeners on the listsNavigator for the events that the child panels will dispatch, with (their bubbles parameter set to true). These listeners could be placed directly on the children themselves, we're just demonstrating bubbling here.

4. For good measure, though, we'll show in this example how one mediator can directly mediate multiple components. Thus, we will not only create a getter for the viewComponent casting it to ListsNavigator, but we'll also set getters for its children, cast to ThingsPanel and StuffPanel.

5. The StuffPanel will send ADD_STUFF or REMOVE_STUFF events. When it does so, it will have set its selectedStuff property to the new stuff object or the one to remove.

6. The ThingsPanel will send ADD_THINGS or REMOVE_THINGS events. When it does so, it will have set its selectedThings property to the new things object or the one to remove.

7. The ListsMediator will hear these events when they bubble up through the ListsNavigator, and the appropriate ListsMediator handler is called.

8. In these event handlers, the ListsMediator will invoke the appropriate Proxy method, passing it the selected stuff or thing, referenced directly from the properties exposed by the custom panels. (see 5)

9. When data in the StuffProxy or ThingsProxy changes (return from service or after an add or update is done) they will send UPDATE_STUFF or UPDATE_THINGS Notifications.

10. The ListsMediator responds to these Notifications by updating the appropriate panel with the list from the corresponding Proxy.

I'll show only the code for the ListsMediator, the ListsNavigator and the ThingsListPanel here. Both panels follow the same pattern and the Proxy you can extrapolate. The 2 key points of this exercise are to show multiple view components mediated by a single mediator, and how to make events bubble up the display hierarchy.

Also, please note, this is chalkboard coding, so its not guaranteed to run.

Hope this helps,

<mx:Panel title="Things List"   xmlns:mx="http://www.adobe.com/2006/mxml">
            public static const ADD_THINGS:String = 'addThings';
            public static const REMOVE_THINGS:String = 'removeThings';
            // Bindable for internal use, as a dataProvider for DataGrid
            [Bindable] public var things:Array;

            public var selectedThing:Object;

            // send the named event
            private function sendEvent( eventName:String ):void
                dispatchEvent( new Event( eventName, true ) );
    <mx:DataGrid id="dg" dataProvider="{things}" click="selectedThing=dg.selectedItem"/>
    <mx:Button label="Add Thing" click="sendEvent(ADD_THING)"/>
    <mx:Button label="Remove Thing" click="sendEvent(REMOVE_THING)" enabled="{(selectedThing!=null)}"/>


<mx:TabNavigator  xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:me="com.me.myapp.view.components.*">
    <me:StuffPanel id='stuffPanel' />
    <me:ThingsPanel  id='thingsPanel'/>

package me.myapp.view
    import flash.events.Event;

    import org.puremvc.as3.interfaces.INotification;
    import org.puremvc.as3.patterns.mediator.Mediator;
    import org.puremvc.as3.patterns.observer.Notification;

    import me.myapp.me.myapp.ApplicationFacade;

    import me.myapp.me.myapp.model.StuffProxy;
    import me.myapp.me.myapp.view.components.StuffPanel;

    import me.myapp.me.myapp.model.ThingsProxy;
    import me.myapp.me.myapp.view.components.ThingsPanel;

    public class ListsMediator extends Mediator
        private var stuffProxy:StuffProxy;
        private var thingsProxy:ThingsProxy;

        public static const NAME:String = 'ListsMediator'

        public function ListsMediator( viewComponent:Object )
            super( NAME, viewComponent );
        // register the event listeners and tell the proxies to fetch data
        override public function onRegister():void
            listsNavigator.addEventListener( StuffPanel.ADD_STUFF, onAddStuff );
            listsNavigator.addEventListener( StuffPanel.REMOVE_STUFF, onRemoveStuff );
            listsNavigator.addEventListener( ThingsPanel.ADD_STUFF, onAddThings );
            listsNavigator.addEventListener( ThingsPanel.REMOVE_STUFF, onRemoveThings );
            stuffProxy = facade.retrieveProxy( StuffProxy.NAME ) as StuffProxy;

            thingsProxy = facade.retrieveProxy( ThingsProxy.NAME ) as ThingsProxy;

        private function get listsNavigator():ListsNavigator
            return viewComponent as ListsNavigator;
        private function get thingsPanel():ThingsPanel
            return listsNavigator.thingsPanel as ThingsPanel;
        private function get stuffPanel():StuffPanel
            return listsNavigator.stuffPanel as StuffPanel;
        private function onAddStuff( event:Event ):void
            stuffProxy.addStuff( stuffPanel.selectedStuff );
        private function onRemoveStuff( event:Event ):void
            stuffProxy.removeStuff( stuffPanel.selectedStuff );
        private function onAddThings( event:Event ):void
            thingsProxy.addThings( thingsPanel.selectedThings );
        private function onRemoveThings( event:Event ):void
            thingsProxy.addThings( thingsPanel.selectedThings );

        override public function listNotificationInterests():Array
            return [
        override public function handleNotification( note:INotification ):void
            switch ( note.getName() )
                case StuffProxy.UPDATE_STUFF:
                    stuffPanel.stuff = stuffProxy.stuff;
                case ThingsProxy.UPDATE_THINGS:
                    thingsPanel.things = thingsProxy.things;
                case ApplicationFacade.SHOW_STUFF:
                    listsNavigator.selectedChild = stuffPanel;

                case ApplicationFacade.SHOW_THINGS:
                    listsNavigator.selectedChild = thingsPanel;

Title: Re: 1 mediator 2 views
Post by: Vander on May 18, 2008, 03:17:58
Thanks cliff...
but ive tried all. :(
i cannot figure out how the addEventListener on mediator never dispares the function :( (never listen the dispatchedevent)

maybe its because im using the application mediator registered with the initial mxml? i guess not... but im a bit lost :(

Title: Re: 1 mediator 2 views
Post by: puremvc on May 18, 2008, 10:32:02
Are you setting the event to bubble?


Title: Re: 1 mediator 2 views
Post by: Vander on May 19, 2008, 12:49:13
dispatchEvent( new Event( TERMINOU_SPLASH, true ));

originally and lastly ive always tried with bubbling... the second parameter, right?

Title: Re: 1 mediator 2 views
Post by: Vander on May 19, 2008, 12:53:26
okay, ive discovered the problem...
it was all about... im using this event on splashscreen

<mx:Image creationComplete="inicia()"/>

ive switched it to a button, and when clicked it was dispached

ive guessed that creationComplete was fired so fast... before something become acessible :)
can you guess me a more 'appropriate' event?

   override public function onRegister():void
          app.addEventListener( SplashScreen.TERMINOU_SPLASH, initScreen );

ive used now a swfloader, for example, and set the autoload to false
i can load the image ok on the onregister... but can you guess me a 'good practice' to how to detect the load complete, for example.. to fire the event?

thanks cliff

Title: Re: 1 mediator 2 views
Post by: puremvc on May 19, 2008, 06:47:11
You might examine the startup process in some of the demos. AppSkeleton, StartupAsOrdered, etc.


Title: Re: 1 mediator 2 views
Post by: Vander on May 20, 2008, 02:03:12
i know by past, that examples.. but im designing my way.. ive got it :) it was some logic error of my part..
but all that you said is always usefull ;) thanks cliff

now im just in one last trouble..
when i change a view on viewstack... it cames not centered... so strange huh?
i can develop a function to recentralize using width/2 etc.. bla bla

any hint?

Title: Re: 1 mediator 2 views
Post by: smartkit on May 22, 2008, 12:38:32
Hey Vander,I got the same question with you about this:
      at someMediator I set addEventListener("someMetaData",function(event:Event)),anyWhere I fire dispatchEvent("someMetaData") success except at creationComplete event .Maybe mediator creation period after mxml creationComplete?
      any idea?
Sorry for my poor english.