Получение родительского компонента через Injector.get(), когда токен может иметь несколько значений
Что я пытаюсь сделать:
- Несколько разных компонентов, которые используют одну директиву
- когда директива вызывается, мне нужно иметь возможность получить родительский / хост-компонент, из которого вызывается директива.
Plnkr -> http://plnkr.co/edit/Do4qYfDLtarRQQEBphW3?p=preview
Просматривая документацию angular.io, я обнаружил, что "Injector" можно использовать для получения родительского компонента в конструкторе.
constructor(private el: ElementRef, private hostComponent:Injector){
el.nativeElement.draggable = 'true';
}
При этом я получаю Injector Object. Из того, что я могу сказать, я тогда должен использовать
this.hostComponent.get(INJECTORTOKEN)
Проблемы, которые мне трудно понять, заключаются в том, что примеры, представленные в Angular, предполагают, что вы знаете тип компонента, который нужно предоставить в токене. то есть:
this.hostComponent.get(Image);
this.hostComponent.get(Box);
В примере pnkr у меня есть два компонента в моем шаблоне
<div>
<h2>Hello {{name}}</h2>
<my-image></my-image> <!-- Uses the "My Directive" -->
<my-box></my-box> <!-- Uses the "My Directive" -->
</div>
Мои вопросы есть в "mydirective.ts". как я могу использовать "injector.get()", когда я не знаю, является ли родительский компонент компонентом "my-image" или "my-box".
в предоставленном примере директива срабатывает "ondrag()". просмотреть консоль, для сообщений журнала.
Любая помощь с благодарностью.
Спасибо, любезно.
1 ответ
Я знаю несколько способов сделать это:
1) Найти родителя по его классу-интерфейсу
Вам нужен токен интерфейса класса провайдера, например:
export abstract class Parent { }
После этого вы должны написать провайдера псевдонимов на Box
а также Image
составная часть
box.ts
providers: [{ provide: Parent, useExisting: forwardRef(() => Box) }]
image.ts
providers: [{ provide: Parent, useExisting: forwardRef(() => Image) }]
затем используйте его в своей директиве, как показано ниже
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;
}
}
}
Вот плункер
2) Введите все ваши родители как Optional
знак
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');
}
}
}
Плункер для этого случая
3) Использование Injector
лайк
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');
}
}
}