You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular独立组件DI问题:父子组件导模块引发NullInjectorError

修复PrimeNG Table在Angular独立组件中的依赖缺失问题

问题根源

该错误源于PrimeNG的SelectableRow指令依赖Table实例注入,但独立组件场景下,Table未被正确注册为可注入提供者;直接在组件providers中添加Table和TableService虽能消除错误,但会生成重复的Table实例。

正确修复方案

1. 在TableComponent中使用viewProviders注册Table

因为Table是TableComponent模板内的核心组件,改用viewProviders而非providers注册,既能保证实例仅作用于当前组件视图层级,又能让父组件的SelectableRow指令正确关联到同一个Table实例:

@Component({
  selector: 'app-table',
  standalone: true,
  imports: [TableModule],
  viewProviders: [Table], // 替换providers为viewProviders
  template: `
    <p-table [value]="data" [columns]="columns">
      <ng-content></ng-content>
    </p-table>
  `
})
export class TableComponent {
  @Input() data: any[] = [];
  @Input() columns: any[] = [];
}

2. AppComponent仅导入必要模块

AppComponent只需导入TableModule以使用SelectableRow指令,无需额外注册提供者:

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [TableModule, TableComponent],
  template: `
    <app-table [data]="tableData" [columns]="tableColumns">
      <ng-template pTemplate="body" let-rowData>
        <tr [pSelectableRow]="rowData">
          <td *ngFor="let col of tableColumns">{{ rowData[col.field] }}</td>
        </tr>
      </ng-template>
    </app-table>
  `
})
export class AppComponent {
  tableData = [...];
  tableColumns = [...];
}

核心原理

  • viewProviders会将实例限定在组件的视图注入器中,仅对当前组件及其内嵌视图(如ng-content传入的内容)可见,完美匹配SelectableRow指令需要关联所在Table实例的需求。
  • 若用providers注册,实例会被挂载到组件的注入器层级,父组件注入时会创建新实例,导致多实例问题。

内容的提问来源于stack exchange,提问作者kerosene

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 19:40:04