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

Angular中ng-content渲染mat-list-option报错:无SelectionList注入提供者

问题原因与解决方案

报错根源

当你在LicenseSelectModalComponent中直接通过ng-content传入mat-list-option时,这些列表项是在父组件的注入上下文中创建的,但mat-list-option依赖SelectionList(Angular Material为mat-selection-list提供的注入令牌),而这个令牌仅在BaseSelectModalComponent内部的mat-selection-list所在的上下文里才会被提供,父组件中没有对应的提供者,因此触发NullInjectorError。

解决方法:改用模板传递自定义内容

放弃ng-content的方式,通过ng-template将自定义列表项模板传递给基础组件,让模板在子组件的上下文里渲染,这样mat-list-option就能获取到SelectionList的提供者。

步骤1:修改BaseSelectModalComponent

  1. 添加输入属性接收自定义模板:
import { Input, TemplateRef } from '@angular/core';

export class BaseSelectModalComponent {
  @Input() customItemTemplate?: TemplateRef<any>;
  // 保留原有其他属性与逻辑
}
  1. 更新模板,根据是否传入自定义模板来渲染内容:
<mat-selection-list class="pt-0" [multiple]="false" #list>
  <!-- 渲染自定义模板 -->
  @if (customItemTemplate) {
    @for (item of items(); track $index) {
      <ng-container 
        [ngTemplateOutlet]="customItemTemplate" 
        [ngTemplateOutletContext]="{ $implicit: item }"
      ></ng-container>
    }
  } @else {
    <!-- 默认列表项 -->
    @for (item of items(); track $index) {
      <mat-list-option [value]="{ id: item.id, name: item.name }">{{ item.name }}</mat-list-option>
    }
  }
</mat-selection-list>

步骤2:修改LicenseSelectModalComponent

将原来的自定义列表项放到ng-template中,并传递给基础组件:

@Component({
  selector: 'app-product-select-modal',
  standalone: true,
  imports: [BaseSelectModalComponent, MatListOption],
  template: `
    <app-base-select-modal 
      title="Seleziona la licenza" 
      [items]="items()" 
      [itemsCount]="count()" 
      [isLoading]="isLoading()" 
      (onClose)="close()" 
      (onConfirm)="confirm($event)"
      [customItemTemplate]="customItemTpl"
    >
    </app-base-select-modal>

    <!-- 自定义列表项模板 -->
    <ng-template #customItemTpl let-item>
      <mat-list-option [value]="item">
        <div>{{ item.product.name }}</div>
        <span>{{ item.key }}</span>
      </mat-list-option>
    </ng-template>
  `,
})
export class LicenseSelectModalComponent {
  // 保留原有其他属性与逻辑
}

为什么这个方法有效?

ng-template本身不会渲染任何内容,只有当通过ngTemplateOutlet在子组件内部渲染时,模板里的mat-list-option才会在子组件的注入上下文里被创建,此时就能找到mat-selection-list提供的SelectionList令牌,解决依赖注入的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 11:50:19