Angular 5中ContentChild获取TemplateRef为undefined的问题排查
解决Angular 5中@ContentChild获取TemplateRef为undefined的问题
我来帮你梳理下问题的核心原因,主要有两个关键细节你没注意到:
1. 选错了生命周期钩子
你在ngAfterViewInit里尝试读取内容投影的模板,但@ContentChild对应的内容投影元素是在**ngAfterContentInit**钩子阶段才完成初始化的。ngAfterViewInit是组件自身视图渲染完毕的时机,这时候内容投影的内容还没被Angular处理完成,自然会拿到undefined。
2. 通过指令获取TemplateRef的方式有误
你直接用@ContentChild(MyColumnDef, {read: TemplateRef})来获取模板引用,但MyColumnDef是你自定义的指令,Angular无法通过这个指令令牌直接读取到TemplateRef。正确的做法是让指令自身持有模板引用,再通过指令实例去获取。
具体修正步骤:
第一步:修改MyColumnDef指令,注入TemplateRef
import { Directive, TemplateRef } from '@angular/core'; @Directive({ selector: '[myColumnDef]' }) export class MyColumnDef { // 注入TemplateRef,让指令实例持有模板引用 constructor(public templateRef: TemplateRef<any>) { } }
第二步:调整my-table组件的查询逻辑和生命周期
import { Component, ContentChild, AfterContentInit } from '@angular/core'; import { MyColumnDef } from './my-column-def.directive'; @Component({ selector: 'my-table', templateUrl: './my-table.component.html' }) export class MyTableComponent implements AfterContentInit { // 先获取MyColumnDef指令实例 @ContentChild(MyColumnDef) columnDef: MyColumnDef; temp: TemplateRef<any>; ngAfterContentInit() { // 从指令实例中拿到模板引用 this.temp = this.columnDef.templateRef; console.log(this.temp); // 现在能正常获取到模板引用了 } }
第三步:保持模板的引用逻辑不变
my-table.component.html里的代码不需要修改,依然可以直接使用temp变量:
<div> Something: <ng-container *ngTemplateOutlet="temp"></ng-container> </div>
这样调整后,页面就能正常显示“Lorem ipsum.”文本了。
内容的提问来源于stack exchange,提问作者Roland Rácz
相关产品推荐
相关产品推荐

