Obtain an associated mediator from a view object

victor.bolinches's Avatar

victor.bolinches

30 May, 2013 03:30 PM

We have the following problem and we don't know how to solve it using robotlegs:

We have a client/server Chat application that allows you to have several ChatView instances, each private chat between users create a ChatView instance. The servers generates a Event handled by a Command. How can we update just the ChatView instance related to the user that is sending the message? Because the mediator is instantianted automatically for each view and is generic. Is there a way of obtaining a view's mediator with the view object? How could we approach this problem?

  1. Support Staff 1 Posted by Shaun Smith on 30 May, 2013 04:08 PM

    Shaun Smith's Avatar

    There are many ways to tackle this, but here is a pretty simple solution.

    Create an auto-incrementing static counter on your mediators that will be used to generate unique ids. Supply this when making service calls, and return it along with the results. Then each mediator can just ignore messages that are not relevant to it (where the id doesn't match).

    class MyMediator
    
      private static var counter:int;
    
      public const id:String = "id" + counter++;
    
      private function serviceResultHandler(result):String
        if (result.id != id) return;
        ...
    

    This assumes that the mediator is listening for service results directly. If you want to differentiate the mediators in a command you'd need to change things a little, but that's the basic idea.

  2. 2 Posted by victor.bolinche... on 31 May, 2013 09:34 AM

    victor.bolinches's Avatar

    According to the best practices of using Robotlegs, mediators should not include any logic (that includes if-for-while ...).
    The solution you proposed includes logic in the mediator and performs a broadcast (since all mediators are subscribed to that event) and I'm worried about the efficiency.

    You said that there are other solutions. Can you explain any other that doesn't perform a broadcast calling?

    Thank you for your answer.

  3. Support Staff 3 Posted by Shaun Smith on 31 May, 2013 02:08 PM

    Shaun Smith's Avatar

    Hi Victor,

    According to the best practices of using Robotlegs, mediators should not include any logic (that includes if-for-while ...).

    I think that's taking it a little too far. The idea is to avoid putting "business logic" in your mediators. A mediator is supposed to be a bridge between a view and the rest of the application. Part of this role involves determining if a message from the application relates to the view that is being mediated.

    and performs a broadcast

    The mediator is not broadcasting, it is subscribing to messages from the app. This is what mediators are designed to do.

    I'm worried about the efficiency

    This would only be a real concern if you had a couple of hundred thousand chat views. In reality, the performance impact would be negligible for a few hundred views.

    You said that there are other solutions.

    Indeed! And the solution I proposed is my least favourite. I only mentioned it because it's something you could implement quickly with your current design.

    Your initial question was actually how to "Obtain an associated mediator from a view object"?

    The framework does not provide a way to do this. Even if it did it would be difficult to work with as a particular view might have any number of mediators. One solution is to manually associate views with mediators in a model. It's a similar approach to the one above.

    Essentially you create a model that allows you to associate views with mediators. Mediators add themselves to this model in their initialize method. The command can use this model to retrieve mediators for views.

    Psuedocode:

    
    // Registered as a singleton
    ChatViewModel  
      private const mediators:Dictionary = new Dictionary();
    
      public function addMediator(mediator, view)
        mediators[view] = mediator;
    
      removeMediatorFor(view)
        delete mediators[view];
    
      getMediatorFor(view)
        return mediators[view];
    
    // In your mediator
    
    [Inject]
    public var view:PrivateChatView;
    
    [Inject]
    public var chatViewModel:ChatViewModel;
    
    public function initialize():void  
      chatViewModel.addMediator(this, view)
    
    
    // In your command
    
    [Inject]
    public var chatViewModel:ChatViewModel;
    
    public function execute()  
      var view = event.view;
      var mediator = chatViewModel.getMediatorFor(view)
    

    Again, this is just one solution.

  4. 4 Posted by victor.bolinche... on 31 May, 2013 02:16 PM

    victor.bolinches's Avatar

    Thank you for explaining!

  5. Support Staff 5 Posted by Shaun Smith on 31 May, 2013 02:25 PM

    Shaun Smith's Avatar

    My pleasure! As I said there are other approaches, but they might require a complete redesign in terms of your service layer. Personally, I use promises, instead of the awkwardly decoupled event->command->service->event->etc flow. See:

    https://github.com/CodeCatalyst/promise-as3
    http://domenic.me/2012/10/14/youre-missing-the-point-of-promises/

  6. Ondina D.F. closed this discussion on 05 Jun, 2013 11:42 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