Instantiate and extend models
hi,
I'm trying to work with a model and extending it.
When say ModelSub extends ModelSuper and I override say function
setSomeVar which
sets a var in ModelSuper, the var in ModelSuper is not being
set.
I think this has to do with how I instantiate the model(s).
Usually, in a non rl project, I would say smt like:
var model:ModelSuper = new ModelSub();
model.setVar("hey");
and the var would be set in ModelSuper.
How do I inject and/or instantiate a sub model in rl to make this work?
I am now just doing:
context.injector.map( MyModel ).asSingleton();
but I think that is not enough?
thanks,
Jeff.
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 JeffW. on 25 Jun, 2013 08:14 AM
I guess I need to use interfaces, sth like described here:
http://knowledge.robotlegs.org/discussions/questions/166-map-multip...
But I don't see how exactly. Do both super and sub model need their own interface?
What do I add in my configure function so that I can inject them in for instance commands? How do you map a model to its interface in RL2?
Tried some things like this:
but these are just wild guesses that don't work..2 Posted by JeffW. on 25 Jun, 2013 08:20 AM
Actually I can set a var in the supermodel from an overridden function in sub model now, so that is not the problem. The question is how I can access that var in another command by injecting the model or its interface...
Support Staff 3 Posted by Ondina D.F. on 25 Jun, 2013 08:56 AM
Hold on, I'll be with you in a bit.
Support Staff 4 Posted by Ondina D.F. on 25 Jun, 2013 09:11 AM
Using a base class
Mapping
SomeModel
BaseModel
SomeClass
Somewhere, call someMethod(); then anotherMethod();
AnotherClass
Using Interfaces:
Mapping:
ISomeOtherModel
SomeOtherModel
SomeClass
Support Staff 5 Posted by Ondina D.F. on 25 Jun, 2013 10:09 AM
If IModel is the interface having a var someProperty:String; and someMethod();, implemented by ModelA and ModelB, then you’ll have to map ModelA
injector.map(IModel).toSingleton(ModelA); in Module A
and
injector.map(IModel).toSingleton(ModelB); in Module B
6 Posted by JeffW. on 25 Jun, 2013 10:12 AM
thanks Ondina, this looks clear to me, and I actually have tried it this way with various results. I looked at my code again and what I'm picturing is that I have common code for multiple contexts. And that I sometimes want to extend this code - a model, command or view - and sometimes not. If I extend a class I can inject the extended class as you describe.
Suppose I have a command that I don't want to extend. I just want to inject the super model into that . This also works - since 1 minute ago - but only if I also map the super model in my config. It feels funny to map both super and sub model. Is this where some smart way of working with interfaces comes in? Something like implementing the interface of a super model onto a sub model.
Support Staff 7 Posted by Ondina D.F. on 25 Jun, 2013 10:25 AM
I’m trying to understand your use case. (reading your questions from the other post and this one). I’m not quite sure what you want to achieve.
The common class would be the interface, IModel, that can reside in a lib, or in the commons folder of the app. In Module A you have ModelA implementing IModel, and in Module B ModelB implementing IModel, both sharing someProperty and someMethod(), and each having (or not) other properties or methods of their own.
The other thing you’re talking about is how to let the shell know about properties changed in ModuleA or B, and/or how to pass this properties from a module to another, right?
You’re talking about a SuperModel or something, but you mean a Shell’s model right?
Support Staff 8 Posted by Ondina D.F. on 25 Jun, 2013 10:29 AM
Maybe what you want is ModuleA dispatching an event to trigger a command in the Shell, which would then set properties on a ModulesModel (your super model?). Then ModuleB, when loaded, would dispatch an event to trigger another command of the Shell, to get the properties from ModulesModel?
9 Posted by JeffW. on 25 Jun, 2013 10:37 AM
Sorry if I'm not clear, which I can imagine.
No, I'm not talking about a shell model, not worried about that at the moment.
I'm talking about a base model that holds functions and properties used by both modules. In my eyes an interface would just contain a list of functions that the module models need to implement whereas a base model, well, contains the actual shared functions and properties. I was hoping to somehow access that base model in a command so that I don't need to write a sub command for every module with its own model injected.
Support Staff 10 Posted by Ondina D.F. on 25 Jun, 2013 01:18 PM
Sorry for the delay, stuff related to my personal projects has been keeping me busy.
What you’re saying is that you want to modify properties in a BaseClass and are expecting that the derived classes would reflect the changes? That’s not possible.
I might be wrong, but I think that you want something like the decorator pattern?
11 Posted by JeffW. on 25 Jun, 2013 01:52 PM
Always glad you answer my posts, no matter if it takes a little longer:)
I don't think I'm expecting derived classes to reflect changes in the BaseModel.
Say I have a BaseModel that reside in my common lib. I want to extend it because there are some differences in how Module A and B save data into the model. So I create ModelA and ModelB, both extending BaseModel.
What I'm trying to avoid is to inherit each and every command that resides in the common lib just to be able to inject ModelA into MyCommandA and ModelB into MyCommandB, which both extend MyCommand. Because what if there is no difference between these 'sub' commands? Then I would just like to use MyCommand. But I cannot inject both ModelA and ModelB into MyCommand. So I was hoping to somehow inject BaseModel or some interface into MyCommand and have access to changes made in ModelA or ModelB. Maybe it's more the other way around: I'm expecting BaseModel to reflect changes in the derived classes.
Is this possible you think? Because if not, I would need to extend all the base commands, even if they are similar for A and B, just to inject ModelA and ModelB.
Support Staff 12 Posted by Ondina D.F. on 25 Jun, 2013 03:03 PM
Hehe, Jeff. The other way around wouldn’t work either.
One thing to notice is that ModelA and ModelB could implement different interfaces, even if they extend a BaseModel. Also, as you’ve noticed, ModelA and ModelB can have their own methods in addition to the ones inherited from a BaseModel.
Or, ModelA and ModelB implement the same interface, and you’d inject the interface into the classes that need them.
In ModuleA, you mapped it like this: injector.map(IModel).toSingleton(ModelA); and you inject it like this:
[Inject] public var model:IModel; //an instance of ModelA will be used
So a command wouldn’t have to know anything about the concrete classes, if you injected the interface.
Also, a class can implement more than one interface, as you probably know.
Another thing is that of what a sub-context inherits from its parent.
Say, you have a mapping in the parent:
injector.map(SomeCrazyClass).asSingleton();
If you use the ModularityExtension without modifying its default settings (ModularityExtension(inherit:Boolean = true, expose:Boolean = true)), then
a sub-context will inherit the mapping of SomeCrazyClass, and you could inject it into your sub-context’s classes.
If you don’t want a sub-context to inherit from its parent, you configure it like this:
.install(MVCSBundle, new ModularityExtension(false))
In this case you have to map SomeCrazyClass in the sub-context.
Also, even if you mapped it in the parent context, and you used the default inherit:Boolean = true, if you map it in the sub-context, the subcontext will use its own mappings.
I just wanted to mention all this, just in case you didn’t know how subcontexts inherit from parent. So, sorry in case you knew.
Now, after that much back and forth I don’t know anymore what to say and I feel like I’m missing your point entirely. I’m getting dizzy ;)
I think it would be easier to attach an example of what you’re trying to achieve, and I could tell you which solution I’d choose after looking at your classes.
13 Posted by JeffW. on 25 Jun, 2013 03:26 PM
Ondina, I got it working now, thanks to your explanation. Sorry you feel dizzy :)
So for now I simply extend ModelA and ModelB with a BaseModel and they both implement the same interface, which I inject in commands that don't have to know about the concrete classes. That interface was what I was looking for!
Actually I wasn't aware of how sub-contexting and inheritance works, will look into that later and maybe move some mappings to the shell. Have a good evening!
Support Staff 14 Posted by Ondina D.F. on 25 Jun, 2013 03:31 PM
Ah, cool! A nice evening to you, too.:)
JeffW. closed this discussion on 25 Jun, 2013 03:55 PM.