Accessing a view's data in its mediator, after a signal (subject is wack, I know!)

Quentin's Avatar

Quentin

11 Nov, 2010 09:33 PM

Hey everyone!
I just started a new project and I do something that doesn't really look clean to me, I'll try to explain what it is (note: this is a plain AS3 project, no MXML or Flex classes involved, and I use the Signals extension).

I have a ThumbnailListStack view that is designed to hold any number of ThumbnailLists. It has a ThumbnailListStackMediator mapped to it. When a specific signal is dispatched a command is executed and the model is updated, as a result, another signal is dispatched (with a payload consisting of the added data and a newly created ThumbnailList). The ThumbnailListStackMediator captures this signal and add the ThumbnailList to the stack's display list.

My problem is: How can the newly created ThumbnailList's mediator (ThumbnailListMediator) be aware of the signal's payload? How do you do to pass this data?

I chose to pass the data to ThumbnailList's constructor, store it a a property and then access this property in the mediator... But that looks ugly right?

Do I miss something?
Got any tip/trick/recommendation?

I'm aware my description of the problem I'm facing might not be very clear, please ask if it's not...

  1. 1 Posted by Stray on 11 Nov, 2010 09:47 PM

    Stray's Avatar

    I use what I call request-response signals for this.

    There's something very similar in this gist here, except that I've got a dataManager class.

    https://gist.github.com/664521

    The basic trick is that the requestSignal dispatches a signal in its payload, and the recipient (or command) responds on this signal. This also means that the response signal only reaches the object that dispatched the requestSignal - so you can have 6 identical view-mediators, dispatch the request from one and only update that single one.

    So - if you inject the request signal into the mediator (as in the gist) and have it fire the request, you can have a command pick that up (in the command map) and fire back the new item (grabbing it from the model that was updated).

    Then your view stays out of the process, mediator stays ignorant of the model etc etc.

  2. 2 Posted by Quentin on 11 Nov, 2010 10:17 PM

    Quentin's Avatar

    Thanks for your answer!

    I'm not sure I perfectly understand your example but it inspired me and here's what I did (I think it matches your suggestion, in a different way).

    I created a TransmitIStackableSignal (with the required data as payload) that the model dispatches just after dispatching the signal that creates and adds the ThumbnailList to the stage. The ThumbnailListMediator listens to that signal (in the onRegister method and once, via addOnce) and, when it captures it, grabs its payload and stores it as a property.

    What do you think?
    Does that look OK?

  3. 3 Posted by Stray on 12 Nov, 2010 10:25 AM

    Stray's Avatar

    That's fine - if the consecutive sending of the signal after you've created the view beats your race condition then that's good.

    The only thing I can see as a weakness is that you're building into your model an assumption about the wider application - that one thing happens directly after another. That might be something that later means that you need to revise your model because the application flow has changed. That's a sign that you're breaking SRP.

    Pragmatically you can keep it just as you've done it and deal with any revisions when they come up.

    Just incase it does come up... here's a more specific-to-your-situation outline of the response-request signals 'pattern'. In a situation where your view addition is async with your data firing, this works and abstracts the application-flow concerns away from any actor in the framework.

    // in context
    signalCommandMap.mapSignalClass(RequestIStackableSignal, RespondWithIStackableSignalCommand);

    // the RequestIStackableSignal requires a signal for the payload
    public function RequestIStackableSignal():void
    {
    super(Signal);
    }

    // in the mediator you inject the request signal, and in onRegister you dispatch a signal to receive the response
    [Inject]
    public var requestDataSignal:RequestIStackableSignal;

    public override function onRegister():void
    {
    var responseSignal:Signal = new Signal(IStackable);
    responseSignal.addOnce(receiveData);
    requestDataSignal.dispatch(responseSignal);
    }

    private function receiveData(dataItem:IStackable):void
    {
    // do whatever you do ...
    }

    // in the command you grab the data model, and the responseSignal is injected (it was dispatched by the mediator)
    [Inject]
    public var responseSignal:Signal;

    [Inject]
    public var stackableStuffModel:IStackableDataModel;

    public override function execute():void
    {
    var dataToSend:IStackable = stackableStuffModel.getLastDataItem();
    responseSignal.dispatch(dataToSend);
    }

    The other pattern I've been playing with is an 'event history' or 'signals history'. These basically just store events / signals and their payloads based on what kind of data they delivered.

    I use a command mapped to the events/signals to make sure that only interesting events/signals are populated into the history.

    Then any actor that is late to the party can request the last update (event or signal) for a datatype that they're interested in.

    The key to it (as always) is strong typing, so that you can be sure that the request is always fulfilled with the correct data. Again, the response signal is set up by the recipient, and you can use the signal valueClasses property to double check before you dispatch. You don't need an extra handler because if you dispatch the actual event (in the case of Events) or the payloads in order (in the case of Signals) then the same handler that is mapped to the signal / eventMap works as your responseSignal handler.

    I'll probably release this as a util when I've had a chance to extract it from the current implementation.

    Hope that helps,

    Stray

  4. 4 Posted by Quentin on 12 Nov, 2010 11:16 AM

    Quentin's Avatar

    Yes, that helps!
    Thanks very much for your suggestion. You're right, it currently works and might not continue to, but for now I'll leave it as is, and probably will change it like you suggest when it breaks...

    Very pedagogical as always, great job.
    By the way, that "event/signals history" pattern looks interesting!

  5. Stray closed this discussion on 10 Feb, 2011 06:14 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