Mapping and Injection with base-classes/implementations regarding ViewComponents and Mediators
Since this site also exists, i wan't to try it for my first
problem with RL:
Ich have the following Classes I talk about here:
- MultiTextViewerBase.as
public class MultiTextViewerBase extends SkinnableContainer...
has all component-logic to handle multiple textElements. - StartPage.mxml
<viewer:MultiTextViewerBase ...
wich defines a text-layout and the mapping for textElements. - MultiTextViewerMediator.as
public class MultiTextViewerMediator extends Mediator implements IMediator
which knows everything that is needed to connect any implementation of MultiTextViewerBase to the app.
My first attempt to use StartPage (beside puting it on the
displaylist) was to write the following inside
context.startup():
mediatorMap.mapView(MultiTextViewerBase,MultiTextViewerMediator);
and this inside of MultiTextViewerMediator:
[Inject]
public var view:MultiTextViewerBase;
but with this there was no Mediator registered for StartPage (what i can see in the log and from the "non-behaviour" of the component).
so thinking maybe it needs the concrete class of the component
to make mapping work, i added this line after the above in
context.startup():
mediatorMap.mapView(MultiTextViewerBase,MultiTextViewerMediator);
mediatorMap.mapView(StartPage, MultiTextViewerMediator);
When starting the app (which always adds a StartPage to the displaylist ;) ) I recieved "error-swiftsuspenders-viewBase-in-Mediator" (see the attached file)
to exclude if there is an error when a mediator is mapped twice
i uncommented the fist of the two lines in
context.startup().
//mediatorMap.mapView(MultiTextViewerBase,MultiTextViewerMediator);
mediatorMap.mapView(StartPage, MultiTextViewerMediator);
but it threw the same error.
The only solution left, I could think of right now was to change
the class of view in MultiTextViewerMediator to StartPage.
[Inject]
public var view:StartPage;
Even if this does not solve my problem, because I wanted to map one mediator to multiple component-implementations (ideally without naming the concrete class(es), but naming it(them) to map to a more specific mediator when I want to), this removed the error-message and (of course) did the mapping and injection / onRegister as usual.
Is, could or will there be any way to do what I wan't?
Thx for help, karfau
Comments are currently closed for this discussion. You can start a new one.
Support Staff 2 Posted by Shaun Smith on 21 Oct, 2009 08:59 PM
Hi Karfau,
I think I see what you're getting at. Could you build a tiny example app (smallest possible) that exhibits this same behavior - that would really help us determine the nature of the problem.
Many thanks,
Shaun
3 Posted by System on 21 Oct, 2009 09:02 PM
An internal ticket was created for this discussion
4 Posted by karfau on 21 Oct, 2009 10:24 PM
Here u go.
Should my attempt work or does it need to be implemented?
(the zipfile only contains the source, using RL v0.95)
It uses FlexSDK 4 (i don't think thats a problem?)
To get the errormessage uncomment lines 13+14 and comment out line 17+18 in view.BasicMediator.
Support Staff 5 Posted by Shaun Smith on 21 Oct, 2009 11:18 PM
Ah! Currently mediators can only be mapped to concrete view classes.
This is for performance. We could look into enabling mapping to
abstract classes as a framework addon, but the performance cost is
going to be pretty substantial. I hope that's not too disapointing -
I've been pondering this issue for some time myself.
Shaun Smith
http://shaun.boyblack.co.za
On 22 Oct 2009, at 12:24 AM, karfau <[email blocked]
> wrote:
Support Staff 6 Posted by Till Schneidereit on 22 Oct, 2009 11:15 AM
Hey Karfau,
I've thought about that issue quite extensively, too. Unfortunately,
Shaun is absolutely right: There's no solution that would have
acceptable performance for this problem.
To give you a quick impression of what we would have to do, here's
what happens now for every view that's added to the display list:
- get the class name through reflection (and cache it after first retrieval)
- make a lookup in our mediator mapping table to see if a mediator is
mapped for that (concrete) view class
- create the mediator if it has been found
And here's what we'd have to do for your use case to work:
- get the class name, all super class names and all implemented
interfaces through reflection (and cache that, but much less
efficiently)
- make a lookup in our mediator mapping table for _each_ of these
class names and interfaces
- create the mediator if it has been found
Keeping in mind that all of that has to be done for absolutely each
view that's added to the display list, I guess you understand why
that's a performance problem.
cheers,
till
7 Posted by karfau on 22 Oct, 2009 09:58 PM
thx for this longer explanation.
Im sure I just don't have any idea of how this works/ is implemented.
But I have a small hope left, that I could get the small addition to the current solution, because my problem is not, that I don't want to map my concrete view (that would be great, but somehow lazy). I would love to map all concrete view-classes that can be handles by ONE Mediator-class (BasicMediator in my ExampleApp), if in this BasicMediator I could make the type the view-component to ViewComponentBase.
So I think (when I look at the errormessage) that my problem is the injection that is not working, because it doesn't find the class to inject. But if the injector (not sure if I name the parts right here) would change the finding of the given viewComponent(vc) to inject for a property(p) from an
classOf(vc)==classOf(p)to an
vc is classOf(p)this would make me happy.
Is this understandable? (I hope)
possible (because some kind of new idea)? (I fear not)
This will be my last attempt in this direction I think.
Just for testing if I have understood u right:
Another approach would be not to do this heavy stuff for(/at) all viewComponents/mediators but only if requested, like in:
mediatorMap.mapGenericView( concreteViewComponentClass:*, mediatorClass:Class, genericAttributeClassOfViewComponentInMediator:*, auto...);e.g.(again with classes from my example-project)
mediatorMap.mapGenericView( ViewComponentImpl, ViewComponentBaseMediator, ViewComponentBase);and would this still be heavy stuff? as it is not like
but names a concrete class to map?
(I can still imagine thatt this is not needed "enough" to make the efford if this would require much code to change. But maybe this is a way to not make the mapping generic but only make the mediator generic.)
So if all of this doesn't work, I need to copy the code of the ViewCompoenteBaseMediator into multiple classes and change the type of the viewComponent to the implementations and map all of these?
wow, still a lot of questions, thx for the support so far,
karfau
Support Staff 8 Posted by Shaun Smith on 22 Oct, 2009 10:35 PM
Aha! That you can do:
mediatorMap.mapModule("view::ViewComponentImpl", ViewComponentBase,
BasicMediator );
mediatorMap.mapModule("view::ViewComponentImpl2", ViewComponentBase,
BasicMediator );
The first param (the Fully Qualified Class Name, or FQCN - note the
"::") is used for the concrete mapping, the second param is what is
injected on Mediator registration.
Hope that helps!
Cheers,
Shaun
9 Posted by karfau on 22 Oct, 2009 10:40 PM
ok, im not using modules, but this also works with normal viewcomponents?
I will test if this does what i want on monday.
thx, and cu
Support Staff 10 Posted by Shaun Smith on 22 Oct, 2009 10:54 PM
Yes, it is badly named I think, but it works with normal view
components. I tested it out on the code you sent me and it works, so
hopefully it's what you were looking for.
cheers,
11 Posted by karfau on 22 Oct, 2009 11:02 PM
Couldn't wait to see if it works the way I want: tested it right now:
Jippie, thats what I wanted!!!
by the way this:
mediatorMap.mapModule( getQualifiedClassName(StartPage), MultiTextViewerBase, MultiTextViewerMediator);also works and is typesafe ;)(So I aks myself: how could I have asked to get this answer in the start ;) )
(double) thx, karfau
Support Staff 12 Posted by Shaun Smith on 22 Oct, 2009 11:14 PM
Awesome! Glad to hear it :)
Cheers,
Shaun
Support Staff 13 Posted by Till Schneidereit on 23 Oct, 2009 12:25 PM
Wow, that's actually something I didn't know as well. Immediate
dramatic increase in usefulness of mapModule for me!
Support Staff 14 Posted by Shaun Smith on 23 Oct, 2009 05:28 PM
Yeh, mapModule is REALLY badly named.. has nothing to do with Flex
modules.. dealing with Flex modules was just the first place I needed
it :)
Ondina D.F. closed this discussion on 29 Aug, 2012 09:16 AM.