Angular Access внутренний компонент ng-шаблона
Допустим, у нас есть компонент под названием TopComponent
с таким шаблоном:
<ng-template #top>
<inner-selector #inner></inner-selector>
</ng-template>
Это простой код:
//... imports ...
@Component({
// selector, styles etc
})
export class TopComponent implements AfterViewInit {
@ViewChild('top') topComp : NgbModal;
// NgbModal is a type provided by some 3rd-party library
// I can't modify it
ngAfterViewInit() {
// let's access the #inner component from here
}
}
Я могу получить доступ к #top
компонент, использующий этот код:
@ViewChild('top') topComponent: TopComponent;
Как я могу получить доступ к #inner
компонент из того же класса?
Я пытался с помощью @ContentChild('inner')
но все еще получаю undefined
,
PS. Я знаю, что могу создать другой компонент, использовать его вместо <ng-template>
и получить доступ ко всем необходимым детям от него. Но можно ли этого как-то избежать?
2 ответа
Использовать потомков @ViewChild('inner', {downndants: true}) inner: InnerSelector;
Вот код для заполнения: https://plnkr.co/edit/MtVhHuAtPXZzC7GLOidF?p=preview
@Component({
selector: 'inner-selector',
template:'inner-selector here'
})
export class InnerSelector {
myVar = 0;
}
@Component({
selector: 'my-app',
template: `
<div>
<ng-template #top>
<inner-selector #inner></inner-selector>
</ng-template>
<ng-container [ngTemplateOutlet]="top"></ng-container>
</div>
`,
})
export class App {
@ViewChild('inner', {descendants: true}) inner: InnerSelector;
constructor() {
this.name = `Angular! v${VERSION.full}`
}
ngAfterViewInit() {
console.log(this.inner);
}
}
Шаблон #top должен быть загружен в какой-то контейнер, чтобы существовать в DOM, и его подхватит @ViewChild. Самый простой метод — использовать простую структурную директиву. В приведенном ниже примере NotReady — это логическое значение, которое вы установили в значение false после завершения работы ngInit.
<div *ngIf="notReady else top">
loading...
</div>
<ng-template #top>
<inner-selector #inner></inner-selector>
</ng-template>
Обратите внимание, что @ViewChild('top') необходимо будет сопоставить как static:false, поскольку он может быть недоступен/существовать до тех пор, пока не будет выполнен ngOnInit(). Затем #top ищется в каждом цикле обнаружения изменений, что полезно при использовании условных директив, таких как *ngIf.
//... imports ...
@Component({
// selector, styles etc
})
export class TopComponent implements AfterViewInit {
notReady: boolean = true;
@ViewChild("top", { static: false }) topComp : NgbModal;
// NgbModal is a type provided by some 3rd-party library
// I can't modify it
ngInit(){
this.notReady = false;
}
ngAfterViewInit() {
// let's access the #inner component from here
}
}