Dependency across mediators
I have two meditators and want to be able to pass events between
them. However, when one is added to the stage, it attempts to
access the other in order to map its listeners, but the other is
not yet created as it's view component has not been added to the
stage.
I have tried creating a command that is triggered once everything
is added to the stage, but still don;t know how I can defer the
dependency injection. What is the correct approach here?
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
1 Posted by Stray on Jun 22, 2010 @ 10:30 AM
Hi Kyma,
your mediators really shouldn't have any clues about each other, so I'm wondering whether there's something gone awry in your understanding of how to use the framework?
The mediators will both have a reference to the shared eventDispatcher. This provides a channel for events passing between mediators. If you dispatch and listen for events on this eventDispatcher then you'll find that they can work together, entirely decoupled.
So - if this is what you're doing:
public class FirstMediator {
[Inject]
public var secondMediator:SecondMediator ...
then it would be a good idea to take a look at some examples.
The correct way to wire mediators together is like this:
// In mediator 1 when something happens that other mediators might care about
dispatch( new SomethingEvent(SomethingEvent.SOMETHING_HAPPENED));
// In mediator 2 in the onRegister function:
onRegister():void
{
eventMap.mapListener(eventDispatcher, SomethingEvent.SOMETHING_HAPPENED, somethingHappenedHandler);
}
This way the mediators can listen for each other's events, without being injected into each other.
The purpose of a mediator is purely to be a way to hook a specific view into your framework without having to put framework code in the view. Mediators should dispatch events on the shared dispatcher when something happens to their own view, and should update their view (via the view API) when events arrive on the framework eventDispatcher that are important to that view.
Generally you shouldn't be injecting anything extra into your mediators - only the view. If you're using signals then you might be injecting some signals as well, but don't inject anything beyond that unless you're deliberately breaking the protocol in way that you understand the consequences of :)
Apologies if I've misunderstood what you're describing.
Generally Commands are for working with models and services (Actors). It's rare that a Command is the best approach for working with views / mediators.
2 Posted by Kyma on Jun 22, 2010 @ 10:38 AM
Thanks for the response. You're right, I had misunderstood the meaning of the eventDispatcher property. I had thought it was looking for an instance of the object dispatching the event. What is the eventDispatcher then?
3 Posted by Stray on Jun 22, 2010 @ 10:55 AM
Hi Kyma
the eventDispatcher is injected into the base classes of the Command, Mediator and Actor classes - so it's available to any class extending those. It is actually called 'eventDispatcher'. (I can see now how that could be confusing!).
It's a single instance of an IEventDispatcher - so if you dispatch an event in a command, mediator or actor (model or service) then every class in your app which extends the base Mediator or Actor has the opportunity to listen for it. So - rather than listening for events on specific objects, you listen on this shared dispatcher.
The dispatch(evt) function which is available in classes that extend Command, Mediator or Actor is a short form of:
eventDispatcher.dispatchEvent(evt)....
it's just there in Command / Mediator / Actor as a convenience.
Generally, you would use the eventMap in the Mediator to listen for events on your view, and on the shared dispatcher. Your code would look like this:
onRegister():void
{
eventMap.mapListener(view, MouseEvent.CLICK, viewClickHandler);
eventMap.mapListener(eventDispatcher, SomeEvent.SOMETHING_HAPPENED, somethingHappenedHandler);
... and more code like this!
}
The reason for using the eventMap and not just doing
eventDispatcher.addEventListener....
is because the eventMap has code for cleaning itself up when the mediator is automatically destroyed if the view leaves the stage.
Usually, Services and Models only dispatch events. They don't listen for them. If you want to respond to an event by using a service or updating a model, this is where you would map a Command to the event in your context, and use the command to call on the service or model API.
It sounds like you could maybe do with some extra background? There are some very good 'getting started' articles on the site, and Joel has written some for Adobe too.
4 Posted by Kyma on Jun 22, 2010 @ 11:03 AM
That all makes sense. Everything's working nicely now. Thanks for your help
Stray closed this discussion on Feb 12, 2011 @ 01:18 AM.