Different Mediator for Each Instance of a View Component?

Daniel's Avatar

Daniel

17 Mar, 2011 10:43 PM

I have a view component that is reused in several situations and I want to have a different mediator for each instance...

Can I create a rule that will map a mediator based on the id of the view component and not its type (since they will all be the same)?

Thanks.

  1. 1 Posted by Stray on 17 Mar, 2011 11:57 PM

    Stray's Avatar

    Hi Daniel,

    this isn't supported.

    There are a couple of workarounds - you can either break out what's different into helpers and compose your mediator at run time, or you can subclass each view with a different class (the approach I use).

    Stray

  2. 2 Posted by Daniel on 18 Mar, 2011 04:54 AM

    Daniel's Avatar

    Thanks Stray,
    I was about to go down the second suggestion, but started experimenting... correct me if I'm wrong, but I don't think it will work...

    I map a default mediator to my view component. In some context, this mediator will remove itself, create a new mediator (mediator2) and register it with the view component. The only issue here is having injection rules satisfied...

    override public function onRegister():void
    {
       if( view.someProperty == true )
           mediatorMap.removeMediator( this );
    }
    
    override public function onRemove():void
    {
       mediatorMap.removeMediator( this );
       if( view.id == "special" )
       {
            // create runtime mediator
        var newMediator:SpecialMediator = new SpecialMediator();
            // register mediator
        mediatorMap.registerMediator( view, newMediator );
    
        // how to satisfy inection mappings? 
            // I could inject the injector here and call injector.injectInto(...) 
            // This requires a mapping though... 'temporary mapping'             
       }
    }
    
  3. Support Staff 3 Posted by Stray on 18 Mar, 2011 08:53 AM

    Stray's Avatar

    Hi Daniel,

    By 'compose your mediator at run time' - I meant using composition of helper classes.

    For example:

    public class SpecialMediatorHelper( ) implements IMediatorHelper
    {
        public function SpecialMediatorHelper(view:SomeView, eventDispatcher:IEventDispatcher, eventMap:IEventMap)
        {
            // keep references to these
        }           
    
        public function wireEventMap( ):void
        {
            eventMap.mapListener(eventDispatcher, SomeEvent.EVENT_FIRED, someHandler, SomeEvent);
        }
    
        protected function someHandler():void
        {
            // do stuff as normal
        }
    

    Because the eventMap you're passing in is the same instance as the one in the mediator, all your mediator clean up etc will be done as normal.

    In the mediator itself you'd have to do something like

    public override function onRegister( ):void
    {
        _helper = createHelper(view.id);
    }
    
    protected function createHelper(viewID:uint):IMediatorHelper
    {
        // you could hand this off to a factory
        if( viewID == 1)
            return new SpecialMediatorHelper(view, eventDispatcher, eventMap);
        if( viewID == 2) // etc
    }
    

    I'd probably take the approach of abstracting it all to a factory, injected into the mediator. The factory only needs one method - createMediatorHelper - taking those 3 params. The factory can then look up the viewID, and you don't have that nasty conditional in your mediator.

    The Factory shouldn't extend Actor because it has its own eventMap and that could get confusing.

    However, I still think subclassing the views is a stronger and simpler approach. If you need them to behave differently then on a practical level they are different classes with a common base. Subclassing expresses this perfectly.

    Hope that's helpful,

    Stray

  4. 4 Posted by Daniel on 19 Mar, 2011 01:53 AM

    Daniel's Avatar

    That's a nice approach.

    I'm curious though... I know its possible to manually register a mediator to an instance of a view component. Is there a way to satisfy the injections in the mediator?

  5. 5 Posted by Stray on 19 Mar, 2011 08:58 AM

    Stray's Avatar

    Hi Daniel - you pass an instance of anything to the injector to satisfy, but you'd have to drag the injector around with you to where you wanted to do it.

    The injector is available already in Commands - so that's the usual approach.

    Check out the IInjector interface in the robotlegs docs for more details of how to use it manually.

    Stray

  6. 6 Posted by Daniel on 19 Mar, 2011 10:03 AM

    Daniel's Avatar

    I was originally using the injectInto of the IInjector interface but it wasn't working and I just realized why---thanks for talking me through!

    For context I'm dynamically attaching different mediators to different instances of the same view component allowing them to behave in very different ways. Looks like there is no problem with registering more than one mediator for a view component either. Now I can essentially snap on and snap off functionality to my view components.

    Daniel

  7. Daniel closed this discussion on 20 Mar, 2011 02:09 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