因为部分组件在ngIf或者ngSwitchCase块中,这样当页面初始化时,因为条件关系,组件并没有被初始化,这时@ViewChild获取的组件类就会是undefined。
要解决这一问题,可以使用@ViewChildren:
import { Component, ViewChildren, QueryList } from '@angular/core'; import { MyComponent } from './mycomponent'; @Component({ selector: 'page-test', template: `<my-component #myComponent></my-component>` }) export class PageTest { @ViewChildren('myComponent') myComp: QueryList<MyComponent>; //在ngAfterViewInit事件中订阅组件变化事件 ngAfterViewInit() { this.myComp.changes.subscribe((item) => { this.myComp.first.init_func(); }); } //或者在ngAfterContentInit事件中订阅组件变化事件 ngAfterContentInit() { this.myComp.changes.subscribe((item) => { this.myComp.first.init_func(); }); } }
网上查到的解决方案,一种是在ngAfterViewInit事件中订阅组件变化事件,另一种是在ngAfterContentInit事件中订阅组件变化事件。暂不清楚两者的差异和优劣。
关于@ViewChild和@ViewChildren的区别:
ViewChild 装饰器用于获取模板视图中的元素,它支持 Type 类型或 string 类型的选择器,同时支持设置 read 查询条件,以获取不同类型的实例。而 ViewChildren 装饰器是用来从模板视图中获取匹配的多个元素,返回的结果是一个 QueryList 集合。
参考链接:
https://leftstick.github.io/tech/2016/04/19/5-rookie-mistakes-to-avoid-with-angular-2
https://stackoverflow.com/questions/40427748/viewchild-always-returns-undefined