Angular 19中ng-template投影组件报错:No provider for _Table!求助
Angular 19投影ng-template至组件时出现NullInjectorError问题解析
问题场景
开发Angular 19应用,包含app-dashboard与app-table组件,使用PrimeNG组件,尝试将ng-template投影至app-table组件,实现代码如下:
TableComponent代码
@Component({ selector: 'app-table', imports: [Skeleton, TableModule, NgTemplateOutlet], template: ` <p-table> <ng-template let-row let-rowIndex="rowIndex" pTemplate="body"> <ng-container [ngTemplateOutlet]="bodyCtx()" [ngTemplateOutletContext]="{ $implicit: row, rowIndex }" /> </ng-template> </p-table> `, changeDetection: ChangeDetectionStrategy.OnPush, }) export class TableComponent<T> { public readonly bodyCtx = contentChild.required<TemplateRef<unknown>>('body'); }
DashboardComponent代码
@Component({ selector: 'app-dashboard', imports: [ TableComponent, ], template: ` <app-table> <ng-template #body let-row let-rowIndex="rowIndex"> <tr> <td>{{ row.name || '-' }}</td> </tr> </ng-template> </app-table> `, changeDetection: ChangeDetectionStrategy.OnPush, }) export class DashboardComponent {}
运行时错误
ERROR NullInjectorError: R3InjectorError(Standalone[_DashboardComponent])[_Table -> _Table -> _Table]: NullInjectorError: No provider for _Table!
问题原因
在Angular 19中,contentChild.required()会生成一个依赖注入令牌,用于获取指定的内容子元素。如果不在组件的providers数组中注册这个令牌,Angular的注入器无法找到对应的提供者,就会抛出上述"No provider"错误(错误信息中的_Table是Angular内部为该令牌生成的名称)。同时原代码直接将contentChild.required()赋值给类属性的方式,会在注入器初始化前执行,进一步导致解析失败。
解决方法
在TableComponent的@Component装饰器中添加providers数组注册令牌,并通过inject()函数获取依赖:
修改后的TableComponent代码
@Component({ selector: 'app-table', imports: [Skeleton, TableModule, NgTemplateOutlet], template: ` <p-table> <ng-template let-row let-rowIndex="rowIndex" pTemplate="body"> <ng-container [ngTemplateOutlet]="bodyCtx" [ngTemplateOutletContext]="{ $implicit: row, rowIndex }" /> </ng-template> </p-table> `, providers: [contentChild.required<TemplateRef<unknown>>('body')], changeDetection: ChangeDetectionStrategy.OnPush, }) export class TableComponent<T> { public readonly bodyCtx = inject(contentChild.required<TemplateRef<unknown>>('body')); }
关键说明
- 必须在
providers中注册contentChild.required()返回的令牌,让Angular注入器能识别并提供对应的内容子元素。 - 使用
inject()函数获取依赖,确保在注入器初始化完成后执行,避免提前访问导致的错误。
内容的提问来源于stack exchange,提问作者TalVik99
相关产品推荐
相关产品推荐

