如果从父级重新初始化 FormGroup,则自定义组件 FormControl 会中断
Custom component FormControl breaking if reinitializing FormGroup from parent
从我的自定义组件中使用的父组件重新初始化 formGroup 时遇到问题。我得到的错误是:
There is no FormControl instance attached to form control element with
name: '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
初始化一切正常。但是当我重新打开窗体所在的模态,并执行相同的组件代码时,出现上述错误。
我发现一遍又一遍地重新初始化 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
,所以不会发生错误。
我找到了一个奇怪的“解决方案”。因此,要重置使用 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 组件自行销毁并重新初始化,但危急时刻需要采取危急措施...
我需要这个 hack,因为我使用 FormGroup 对象将表单的结果保存到临时结果数组中,每个结果都可以随意重新打开和编辑。以后我会做基于ngModel的表单状态保存,来避免这个问题,但是这里有一个临时的解决方案。
编辑 1
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();
检测更改将同步 运行 更改检测和更新视图,从而删除旧的表单组。
我的解决方案是将 formControlName
替换为 formControl
。
而不是
<my-custom-component formControlName="selectedCompany"></my-custom-component>
使用
<my-custom-component [formControl]="addForm.controls['selectedCompany']"></my-custom-component>
或使用一些 getMethod 获取 formControl
也适用,但有错误:
There is no FormControl instance attached to form control element with
path
我用了一些 FormArray
。
从我的自定义组件中使用的父组件重新初始化 formGroup 时遇到问题。我得到的错误是:
There is no FormControl instance attached to form control element with name: '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
初始化一切正常。但是当我重新打开窗体所在的模态,并执行相同的组件代码时,出现上述错误。
我发现一遍又一遍地重新初始化 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
,所以不会发生错误。
我找到了一个奇怪的“解决方案”。因此,要重置使用 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 组件自行销毁并重新初始化,但危急时刻需要采取危急措施...
我需要这个 hack,因为我使用 FormGroup 对象将表单的结果保存到临时结果数组中,每个结果都可以随意重新打开和编辑。以后我会做基于ngModel的表单状态保存,来避免这个问题,但是这里有一个临时的解决方案。
编辑 1
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();
检测更改将同步 运行 更改检测和更新视图,从而删除旧的表单组。
我的解决方案是将 formControlName
替换为 formControl
。
而不是
<my-custom-component formControlName="selectedCompany"></my-custom-component>
使用
<my-custom-component [formControl]="addForm.controls['selectedCompany']"></my-custom-component>
或使用一些 getMethod 获取 formControl
也适用,但有错误:
There is no FormControl instance attached to form control element with path
我用了一些 FormArray
。