Issue subclassing a Mediator
Hi,
i'm currently building an app that uses the composite pattern. For this reason i have a BaseView Class that's the base class for every view within the pattern. So i decided to create a BaseViewMediator to manage the shared functionality of each view, with the idea being to then subclass this Mediator for any view that needed additional management.
This all worked fine, until i attempted to subclass the BaseViewMediator. So i have,
LoginView extends BaseView
and
LoginViewMediator extends BaseViewMediator
Then in a Command i have
mediatorMap.mapView( BaseView, BaseViewMediator );
mediatorMap.mapView( LoginView, LoginViewMediator );
The BaseViewMediator Class has a public var that's marked for injection called 'view'
[Inject] public var view : BaseView;
But when LoginView gets added to the stage and the LoginViewMediator is created, i get this error,
Error: Injector is missing a rule to handle injection into target [object LoginViewMediator]. Target dependency: com.myApp.view.pages::BaseView
I'm presuming that when a view is injected into a Mediator, the injection is being handled automatically, i.e even though the view Class mapped to the Mediator hasn't been mapped for injection explicitly, the injector knows to assign the instance of the class associated with the Mediator. However, i'm a bit stumped, as i'd presumed that as LoginView is a subclass of BaseView, it wouldn't have any issue assigning it to 'view'?
I hope this all makes sense, any help would be appreciated.
Cheers,
James
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
Support Staff 1 Posted by Shaun Smith on 10 Aug, 2010 03:41 PM
Hi James,
Unfortunately there are some limitations with the current implementation of the Mediator Map. When the mediator is mapped we store a config object that keeps track of the "type" of view to be injected:
http://github.com/robotlegs/robotlegs-framework/blob/v1.1.2/src/org...
Later, when the mediator is created, we use that information to do a temporary mapping for the view component:
http://github.com/robotlegs/robotlegs-framework/blob/v1.1.2/src/org...
As you've discovered, this means that you can't specify two view injection points in the same mediator (one of them won't have been mapped and the DI container will throw an error).
A work-around is to specify the
injectViewAs
parameter as the BaseView type for all the mappings and then use a getter to up-cast the injected property in your derived mediators. Something like this:And then in LoginViewMediator:
Hope that helps!
2 Posted by Nikos on 13 Aug, 2010 01:36 PM
why are you adding stuff to the mediatorMap in a command and not the context?
Support Staff 3 Posted by Shaun Smith on 13 Aug, 2010 02:01 PM
With complex projects (one's where there is a LOT of configuration) it is common to break configuration up into multiple Commands (e.g. MapControllersCommand, MapModelsCommand, MapServicesCommand, MapViewsCommand) and bind these commands to a STARTUP event. It's usually only with small projects that one would configure all rules directly in the context in the startup() hook.
4 Posted by jamesr on 13 Aug, 2010 02:10 PM
Thanks for the help Shaun. I ended up casting the viewComponent in the baseViewMediatior to BaseView
protected function get baseView():BaseView
{
}
and then used Inject to inject the actual view class into the subclass of BaseViewMediator.
Support Staff 5 Posted by Shaun Smith on 13 Aug, 2010 02:24 PM
Yup, that's another way to do it. In a future version we should be able to handle this more elegantly :)
6 Posted by Nikos on 13 Aug, 2010 02:31 PM
sheesh thats ugly :)
Stray closed this discussion on 10 Feb, 2011 05:34 PM.