Understanding ViewChildren, ContentChildren, and QueryList in Angularcss
有時候,咱們想要在父組件中訪問它的子組件。在Angular中能夠使用ViewChildren
ViewChild
ContentChildren
來實現對子組件的訪問。html
假設,咱們封裝了一個Alert
子組件app
// alert.component.html <h1 (click)="alert()">{{type}}</h1>
import { Component, OnInit, Input } from '@angular/core'; @Component({ selector: 'app-alert', templateUrl: './alert.component.html', styleUrls: ['./alert.component.scss'] }) export class AlertComponent implements OnInit { @Input() type = 'success'; constructor() { } ngOnInit() { } alert() { console.log('alert'); } }
而後,在HomeComponent 使用它屢次this
// home.component.html <app-alert></app-alert> <app-alert type="info"></app-alert> <app-alert type="danger"></app-alert>
使用 @ViewChildren
decorator 來獲取全部的子組件。@ViewChildren
支持的參數包括 directive
、component type
和 模板變量。3d
// home.component.js export class HomeComponent implements OnInit, AfterViewInit { @ViewChildren(AlertComponent) alerts: QueryList<AlertComponent>; ngAfterViewInit() { console.log(this.alerts); this.alerts.forEach(alertInstance => console.log(alertInstance)); } }
控制檯打印出了3個AlertComponent的instance 對象code
當@ViewChildren
的參數是 component
或者 directive
時,會返回component
或者 directive
的實例對象。component
當@ViewChildren
的參數是模板變量時,會分兩種狀況。若是模板變量對應的是一個component
,則返回實例對象;若是模板變量對應的是一個普通html標籤,則返回本地元素的引用 ElementRef
。htm
// home.component.html <div class="col" #div> <app-alert #alert1></app-alert> <app-alert type="info"></app-alert> <app-alert type="danger"></app-alert> </div>
// home.component.ts export class HomeComponent implements OnInit, AfterViewInit { @ViewChildren('alert1') alerts: QueryList<any>; @ViewChildren('div') div: QueryList<any>; ngAfterViewInit() { console.log(this.div); this.div.forEach(inst => console.log(inst)); console.log(this.alerts); this.alerts.forEach(alertInstance => console.log(alertInstance)); } }
須要注意的是:若是使用了
*ngIf
來控制子組件是否顯示,只有在子組件顯示的時候,纔可以獲取到子組件。對象
若是在父組件中只有一個子組件,使用@ViewChild
比較合適。blog
// home.component.ts export class HomeComponent implements OnInit, AfterViewInit { @ViewChild('alert1') alerts: any; @ViewChild('div') div: any; ngAfterViewInit() { console.log(this.div); console.log(this.alerts); } }
若是不想獲取子組件的實例,只想訪問Dom元素,能夠添加read
參數
// home.component.ts @ViewChild('alert1', {read: ElementRef}) alerts: any;
@ViewChildren
也支持read 參數。
You need this token when you need to create templates or components dynamically。當須要動態建立組件時,須要這個參數。
@ViewChildren(AlertComponent, {read: ViewContainerRef}) alerts: QueryList<AlertComponent>;