Angular 9 如何从TemplateRef中获取子组件的实例
问题原因
你在Angular8中使用的_projectedViews属于Angular旧版ViewEngine渲染引擎的内部私有属性,本身不属于官方公开的稳定API,没有跨版本兼容性承诺。Angular9默认切换为IVy渲染引擎后,内部视图结构完全重构,因此该属性被移除,原有写法失效。
解决方案
优先使用Angular官方公开的稳定API实现需求,不要依赖任何下划线开头的内部私有属性。
方案1:直接查询子组件实例(最推荐)
直接通过子组件的模板引用变量或者组件类查询实例,不受ng-template包裹的影响:
- 模板代码:
<ng-template #templateName> <child-component #childComp></child-component> </ng-template>
- 组件代码:
// 方式1:通过模板变量查询 @ViewChild('childComp', { static: false }) childComponent: ChildComponent; // 方式2:直接通过子组件类查询,无需额外添加模板变量 @ViewChild(ChildComponent, { static: false }) childComponent: ChildComponent;
注意:如果ng-template是运行时动态渲染(如搭配*ngIf、ngTemplateOutlet使用),需要等模板渲染完成后再访问实例,也可以在ngAfterViewInit生命周期钩子中访问。
方案2:动态渲染模板时从嵌入视图获取
如果你是通过ViewContainerRef.createEmbeddedView动态创建模板视图,可以从返回的EmbeddedViewRef实例中获取:
@ViewChild('templateName') template: TemplateRef<any>; @ViewChild('viewContainer', { read: ViewContainerRef }) viewContainer: ViewContainerRef; getChildComponent() { // 动态创建嵌入视图 const embeddedView = this.viewContainer.createEmbeddedView(this.template); // 触发变更检测,确保子组件初始化完成 embeddedView.detectChanges(); // 遍历查找子组件实例 const childComponent = embeddedView.rootNodes .find(node => node.tagName.toLowerCase() === 'child-component') ?.__ngContext__?.find(ctx => ctx instanceof ChildComponent); }
注意:该方法用到的__ngContext__仍属于半内部属性,仅作为临时兼容方案使用,仍优先推荐方案1。
内容的提问来源于stack exchange,提问作者achjavaoracle
相关产品推荐
相关产品推荐

