从我的自定义组件中使用的父组件重新初始化formGroup时出现问题。我得到的错误是:
表单控件元素没有附加FormControl实例 名称:'selectedCompany'
HTML :
<form [formGroup]="addForm">
...
<my-custom-component formControlName="selectedCompany"></my-custom-component>
...
</form
<my-custom-component>
是根据创建自定义formControl组件的有效方式创建的:https://blog.thoughtram.io/angular/2016/07/27/custom-form-controls-in-angular-2.html#implementing-controlvalueaccessor
组件
这是初始化formGroup变量addForm
:
let formTemp: any = {
selectedCompany: new FormControl(null, [Validators.required]),
}
this.addForm = this._formBuilder.group(formTemp);
第一次初始化addForm
一切都很好。但是当我重新打开表单所在的模态,并执行相同的组件代码时,会出现上述错误。
答案 0 :(得分:15)
我发现反复重新初始化formGroup并不好,因为组件会丢失对旧formGroup的引用。
如果设置值是显示新表单所需的值,.setValue
就是这里的解决方案:
<强>组件强>
不是重新初始化addForm
,而是检查先前是否已初始化addForm
,如果是,则仅为现有FormControls
设置值:
if (this.addForm) {
this.addForm.setValue({
selectedCountry: null
})
} else {
let formTemp: any = {
selectedCompany: new FormControl(null, [Validators.required]),
}
this.addForm = this._formBuilder.group(formTemp);
}
通过这种方式,我想,旧addForm
的引用不会丢失,因此不会发生错误。
答案 1 :(得分:1)
我找到了一个奇怪的“解决方案”。因此,要重置子组件,这些子组件将使用formGroup并在换出时感到困惑。我使用这个技巧。
comp.ts
public flicker: boolean = false;
reInit() {
this.flicker = true;
this.addForm = this._formBuilder.group({
selectedCompany: new FormControl(null, [Validators.required]),
});
setTimeout( () => this.flicker = false, 200); //On very heavy pages, timeout ensures that the flicker hack works as expected.
}
comp.html
<form [formGroup]="addForm" *ngIf="!flicker">
...
<my-custom-component formControlName="selectedCompany"></my-custom-component>
...
</form>
可怕的黑客,它基本上强制formGroup组件销毁并重新初始化自身,但绝望的时代要求采取绝望的措施...
我需要这个技巧,因为我使用FormGroup对象将表单的结果保存到临时结果数组中,每个结果都可以随意重新打开和编辑。将来,为了避免这个问题,我将基于ngModel的表单状态进行保存,但是这里有一个临时解决方案。
setTimeout( () => this.flicker = false, 200); //On very heavy pages, timeout ensures that the flicker hack works as expected.
有一种更好的同步闪烁方式
this.flicker = true;
this._changeDetectorRef.detectChanges();
this.flicker = false;
this._changeDetectorRef.detectChanges();
detect changes将同步运行变更检测并更新视图,从而删除旧的表单组。
答案 2 :(得分:1)
为此,我的解决方案是将formControlName
替换为formControl
。
代替
<my-custom-component formControlName="selectedCompany"></my-custom-component>
使用
<my-custom-component [formControl]="addForm.controls['selectedCompany']"></my-custom-component>
或使用一些getMethod来获取formControl
也会出现错误:
没有任何FormControl实例附加到带有 路径
我使用过一些FormArray
。