能否用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
相关产品推荐
相关产品推荐

