Reusing mediators with views

xIke's Avatar

xIke

28 Apr, 2013 04:42 AM

I have a very simple view that shows a list of items (populated from a model) and has buttons for interacting with the selected item. My mediator works great and I want to use it for another view that simply shows items from a different model. What's the best way to reuse a mediator with different views? The only thing that needs to change for the mediator is the injected model and view.

In the past I did this by making a base mediator that had a function for getting the model which any subclasses would override. Is there a better way to do this? Thanks for any help!

Here's my mediator:

package com.social.views.friends
{
    import com.social.events.DataEvent;
    import com.social.events.ModelEvent;
    import com.social.models.FriendsModel;
    
    import flash.events.MouseEvent;
    
    import mx.collections.ArrayCollection;
    
    import spark.events.IndexChangeEvent;
    
    import org.robotlegs.mvcs.Mediator;
    
    public class FriendListPaletteMediator extends Mediator
    {
        [Inject]
        public var view:FriendListPalette;
        
        [Inject]
        public var model:FriendsModel;
        
        override public function onRegister():void
        {
            super.onRegister();
            
            addContextListener(ModelEvent.SELECTION_CHANGED,context_selectionChangedHandler,ModelEvent);
            addContextListener(ModelEvent.ITEMS_CHANGED,context_itemsChangedHandler,ModelEvent);
            
            eventMap.mapListener(view.list, IndexChangeEvent.CHANGE, list_changeHandler, IndexChangeEvent);
            eventMap.mapListener(view.newButton, MouseEvent.CLICK, newButton_clickHandler, MouseEvent);
            eventMap.mapListener(view.deleteButton, MouseEvent.CLICK, deleteButton_clickHandler, MouseEvent);
            
            updateState();
            updateData();
            updateSelection();
        }
        
        //----------------------------------
        //  global listeners
        //----------------------------------
        
        protected function context_itemsChangedHandler(event:ModelEvent):void
        {
            if (event.model == model)
            {
                updateData();
            }
        }
        
        protected function context_selectionChangedHandler(event:ModelEvent):void
        {
            if (event.model == model)
            {
                updateSelection();
                updateState();
            }
        }
        
        //----------------------------------
        //  view listeners
        //----------------------------------
        
        protected function list_changeHandler(event:IndexChangeEvent):void
        {
            var e:DataEvent = new DataEvent(DataEvent.EDIT_ITEM);
            e.model = model;
            e.item = view.list.selectedItem;
            dispatch(e);
        }
        
        protected function newButton_clickHandler(event:MouseEvent):void
        {
            model.selectedItem = model.NEW_ITEM;
        }
        
        protected function deleteButton_clickHandler(event:MouseEvent):void
        {
            var e:DataEvent = new DataEvent(DataEvent.DELETE_ITEM);
            e.model = model;
            e.item = view.list.selectedItem;
            dispatch(e);
        }
        
        //----------------------------------
        //  update methods
        //----------------------------------
        
        protected function updateData():void
        {
            view.list.dataProvider = new ArrayCollection(model.items);
        }
        
        protected function updateSelection():void
        {
            view.list.selectedItem = model.selectedItem;
        }
        
        protected function updateState():void
        {
            if (model.selectedItem != null && model.selectedItem != model.NEW_ITEM)
            {
                view.currentState = view.normalState.name;
            }
            else
            {
                view.currentState = view.emptyState.name;
            }
        }
    }
}
  1. Support Staff 1 Posted by Ondina D.F. on 28 Apr, 2013 09:27 AM

    Ondina D.F.'s Avatar

    Hello,

    Would it be a solution for you to inject the views and models as an interface into your mediator?
    Of course, you’d have to map them accordingly.
    mediatorMap.mapView(FirstView, SomeMediator, ISomeView);
    mediatorMap.mapView(SecondView, SomeMediator, ISomeView);

    For rl1 see this utility: https://github.com/piercer/robotlegs-extensions-ViewInterfaceMediat...

    Also, read Stray’s answer about using factories in this discussion:
    http://knowledge.robotlegs.org/discussions/questions/290-mediating-...

    Some interesting discussions as well:
    http://knowledge.robotlegs.org/discussions/problems/165-mediators-a...

    http://knowledge.robotlegs.org/discussions/problems/142-issue-subcl...

    No idea if this is working, but you can take a look at it:
    http://knowledge.robotlegs.org/discussions/suggestions/34-mapping-a...

    Let me know whether your question has been answered or not.

    Ondina

  2. 2 Posted by xIke on 28 Apr, 2013 09:33 PM

    xIke's Avatar

    Thanks. Those links helped a lot. I started to go down the path of injecting the views and models as interfaces, but it felt like I was adding a lot of glue code (making a view implement an interface for accessing its elements). I ended up just copying the code...it's very lightweight, and like one of those links mentioned, it's simply linking up basic view behaviors with a model.

    Thanks a lot!

  3. Support Staff 3 Posted by Ondina D.F. on 29 Apr, 2013 12:31 PM

    Ondina D.F.'s Avatar

    Glad it was helpful :)

  4. Ondina D.F. closed this discussion on 29 Apr, 2013 12:31 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