Angular5 父组件获取子组件实例( ViewChildren、ViewChild用法)

原文链接

Understanding ViewChildren, ContentChildren, and QueryList in Angular

使用场景

有时候,我们想要在父组件中访问它的子组件。在Angular中可以使用ViewChildren ViewChild ContentChildren 来实现对子组件的访问。

假设,我们封装了一个Alert子组件

// 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 使用它多次

// home.component.html
    <app-alert></app-alert>
    <app-alert type="info"></app-alert>
    <app-alert type="danger"></app-alert>

ViewChildren

使用 @ViewChildren decorator 来获取所有的子组件。@ViewChildren 支持的参数包括 directivecomponent type 和 模板变量。

// 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 对象

725304-20181126163253686-2146804403.png

@ViewChildren的参数是 component 或者 directive时,会返回component 或者 directive的实例对象。

@ViewChildren的参数是模板变量时,会分两种情况。如果模板变量对应的是一个component,则返回实例对象;如果模板变量对应的是一个普通html标签,则返回本地元素的引用 ElementRef

// 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));
  }
}

725304-20181126165021275-1060831411.png

需要注意的是:如果使用了 *ngIf 来控制子组件是否显示,只有在子组件显示的时候,才能够获取到子组件。

ViewChild

如果在父组件中只有一个子组件,使用@ViewChild比较合适。

// 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);
  }
}

725304-20181126170201507-1327262421.png

read 参数

ElementRef

如果不想获取子组件的实例,只想访问Dom元素,可以添加read参数

// home.component.ts
@ViewChild('alert1', {read: ElementRef}) alerts: any;

@ViewChildren也支持read 参数。

725304-20181126170652433-1484155744.png

ViewContainerRef

You need this token when you need to create templates or components dynamically。当需要动态创建组件时,需要这个参数。

  @ViewChildren(AlertComponent, {read: ViewContainerRef}) alerts: QueryList<AlertComponent>;

725304-20181126172304370-1425995062.png

转载于:https://www.cnblogs.com/liulei-cherry/p/10021340.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值