Angular 使用FormControl.setValue()时多次调用ControlValueAccessor.writeValue()

Angular 使用FormControl.setValue()时多次调用ControlValueAccessor.writeValue(),angular,angular-reactive-forms,Angular,Angular Reactive Forms,考虑以下反应式表单设置: 让我们有自定义的SimpleInputComponent,它实现ControlValueAccessor接口。将它添加到使用ngIf指令包装的应用程序模板中,这样我们就可以在ngIf表达式更改时重新调用SimpleInputComponent的生命周期 由于使用formControlName指令将SimpleInputComponent绑定到FormControl实例,您可以通过调用FormControl.setValue方法更改其值 我希望FormControl.se

考虑以下反应式表单设置:

让我们有自定义的
SimpleInputComponent
,它实现
ControlValueAccessor
接口。将它添加到使用
ngIf
指令包装的应用程序模板中,这样我们就可以在
ngIf
表达式更改时重新调用
SimpleInputComponent
的生命周期

由于使用
formControlName
指令将
SimpleInputComponent
绑定到
FormControl
实例,您可以通过调用
FormControl.setValue
方法更改其值

我希望
FormControl.setValue
能够触发
SimpleInputComponent.writeValue
一次。不幸的是,事实并非如此

FormControl.setValue
调用
SimpleInputComponent.writeValue的次数与调用
SimpleInputComponent
的生命周期的次数相同

现在,要模拟问题,您至少需要两个组件:

SimpleInputComponent:
从'@angular/core'导入{Component,forwardRef,Input};
从“@angular/forms”导入{NG_VALUE_访问器,ControlValueAccessor,FormControlName};
@组成部分({
选择器:“简单输入文本”,
模板:`
`,
供应商:[
{provide:NG_VALUE_访问器,useExisting:forwardRef(()=>SimpleInputComponent),multi:true}
]
})
导出类SimpleInputComponent实现ControlValueAccessor{
私有值:字符串;
构造函数(){}
传播更改:any=()=>{};
propagateTouch:any=()=>{};
onBlur(){
这个.touch();
}
onChange(事件){
此.propagateChange(event.target.value);
}
writeValue(值:任意):无效{
log('writeValue()调用');
这个值=值;
}
注册变更(fn:任何):无效{
这一变化=fn;
}
注册表项(fn:()=>void):void{
此参数=fn;
}
setDisabledState?(isDisabled:boolean):void{}

}
我看到此修复程序的PR仍处于打开状态。你可以在这里查看

同时,对于解决方案,您可以在SimpleInputComponent中定义Ngondestry,如下所示

ngOnDestroy() {
    if (this.ngControl) {
      this.ngControl.reset();
      this.ngControl.valueAccessor &&
        (this.ngControl.valueAccessor.writeValue = () => {});
    }
  }

这似乎是一个已知的问题。看见