What I'm trying to do:
Plnkr -> http://plnkr.co/edit/Do4qYfDLtarRQQEBphW3?p=preview
In looking at the angular.io documentation, I've found that "Injector" can be used to obtain the parent Component in the constructor
constructor(private el: ElementRef, private hostComponent:Injector){
el.nativeElement.draggable = 'true';
}
In doing so, I get Injector Object. From what I can tell I am then supposed to use
this.hostComponent.get(INJECTORTOKEN)
The issues I'm having difficulty grasping is that, the examples provided in Angular, make the assumption that you know the type of Component to provide in the token. ie:
this.hostComponent.get(Image);
this.hostComponent.get(Box);
In the pnkr example, I have two components in my template
<div>
<h2>Hello {{name}}</h2>
<my-image></my-image> <!-- Uses the "My Directive" -->
<my-box></my-box> <!-- Uses the "My Directive" -->
</div>
My questions is, in the "mydirective.ts". how can I leverage the "injector.get()" when I don't know if the parent is an "my-image" or 'my-box' component.
in the sample provided, the directive is triggered "ondrag()". view the Console, for log messages.
Any assistance is gratefully appreciated.
Thank you kindly.
I know several ways to do that:
1) Find a parent by its class-interface
You need the provider's class-interface token like:
export abstract class Parent { }
After that you should write an alias provider on Box
and Image
component
box.ts
providers: [{ provide: Parent, useExisting: forwardRef(() => Box) }]
image.ts
providers: [{ provide: Parent, useExisting: forwardRef(() => Image) }]
then use it in your directive as shown below
myDirective.ts
export class MyDirective {
constructor(@Optional() private parent: Parent){}
@HostListener('dragstart',['$event']) ondragstart(event){
switch(this.parent.constructor) {
case Box:
console.log('This is Box');
break;
case Image:
console.log('This is Image');
break;
}
}
}
Here's Plunker
2) Inject all your parents as Optional
token
myDirective.ts
export class MyDirective {
constructor(
@Optional() private image: Image,
@Optional() private box: Box){}
@HostListener('dragstart',['$event']) ondragstart(event){
if(this.box) {
console.log('This is Box');
}
if(this.image) {
console.log('This is Image');
}
}
}
Plunker for this case
3) Use Injector
like
export class MyDirective {
constructor(private injector: Injector){}
@HostListener('dragstart',['$event']) ondragstart(event){
const boxComp = this.injector.get(Box, 0);
const imageComp = this.injector.get(Image, 0);
if(boxComp) {
console.log('This is Box');
}
if(imageComp) {
console.log('This is Image');
}
}
}