#angular #angular2-injection
#angular #angular2-инъекция
Вопрос:
Что я пытаюсь сделать:
- Несколько разных компонентов, которые используют одну директиву
- при вызове директивы мне нужно иметь возможность получить родительский / хост-компонент, из которого вызывается директива.
Plnkr -> http://plnkr.co/edit/Do4qYfDLtarRQQEBphW3?p=preview
При рассмотрении angular.io документация, я обнаружил, что «Инжектор» можно использовать для получения родительского компонента в конструкторе
constructor(private el: ElementRef, private hostComponent:Injector){
el.nativeElement.draggable = 'true';
}
При этом я получаю объект инжектора. Из того, что я могу сказать, я должен использовать
this.hostComponent.get(INJECTORTOKEN)
Проблемы, которые мне трудно понять, заключаются в том, что в примерах, приведенных в Angular, предполагается, что вы знаете тип компонента, который нужно указать в token. ie:
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;
}
}
}
Вот Plunker
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');
}
}
}
Комментарии:
1. Большое вам спасибо. это решило проблему и также предлагает мне путь вперед по ряду различных проблем. Merci Beaucoup!