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>;