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

能否用ngTemplateOutletInjector使NgModel在表单嵌入式模板中生效?需依赖哪些?

解决Angular表单中ngTemplateOutlet的NgModel集成问题

从Angular 14开始,ngTemplateOutlet指令新增了ngTemplateOutletInjector参数,它用于指定嵌入式视图要使用的注入器。

此前在表单中嵌套ngTemplateOutlet时,层级注入是核心障碍,比如以下结构:

<form #form="ngForm">
    <ng-container *ngTemplateOutlet="tRef"></ng-container>
</form>

模板内的NgModel无法自动关联到父表单,现在可以通过自定义注入器解决该问题,关键是明确注入器需要提供的依赖项。

NgModel的依赖分析

NgModel构造函数的依赖项如下:

@Optional() @Host() parent: ControlContainer,
@Optional() @Self() @Inject(NG_VALIDATORS) validators: (Validator|ValidatorFn)[],
@Optional() @Self() @Inject(NG_ASYNC_VALIDATORS) asyncValidators: (AsyncValidator|AsyncValidatorFn)[],
@Optional() @Self() @Inject(NG_VALUE_ACCESSOR) valueAccessors: ControlValueAccessor[],
@Optional() @Inject(ChangeDetectorRef) private _changeDetectorRef?: ChangeDetectorRef|null)

需提供的核心内容

要让模板内的NgModel和外部表单正常集成,注入器中必须提供ControlContainer,也就是当前表单的NgForm实例。因为NgModel需要通过parent(即ControlContainer)注册到父表单,这是关联表单的核心逻辑。

其他依赖项均为@Optional()标记,无需强制提供:

  • NG_VALIDATORS、NG_ASYNC_VALIDATORS:仅当模板内控件需要自定义验证逻辑时才需提供,否则Angular会使用控件自身的验证器(若存在)。
  • NG_VALUE_ACCESSOR:通常由input、select等表单控件组件自身提供,无需额外注入。
  • ChangeDetectorRef:Angular会自动从视图层级中获取,除非需要自定义变更检测逻辑,否则无需手动提供。

简单实现示例

// 获取表单的NgForm实例
@ViewChild('form') form!: NgForm;

// 基于表单注入器创建自定义注入器
customInjector = Injector.create({
  providers: [
    { provide: ControlContainer, useValue: this.form }
  ],
  parent: this.form.injector
});

模板中使用自定义注入器:

<form #form="ngForm">
    <ng-container *ngTemplateOutlet="tRef; injector: customInjector"></ng-container>
</form>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 14:15:38