我正在使用一个角度应用程序,我需要在表单记录中动态添加/删除表单控件(复选框)。
我在 stackblitz 上创建了此行为的最小版本,重要的内容在下面的代码中。
private formBuilder = inject(NonNullableFormBuilder);
form = this.formBuilder.record<boolean>({});
nestedForm = this.formBuilder.group({
field1: [``],
subRecord: this.formBuilder.record<boolean>({}),
});
// This works without problem
removeRandomFormControls() {
const record = this.form;
Object.keys(record.controls).forEach((key) => {
if (Math.random() > 0.5) {
return;
}
record.removeControl(key, { emitEvent: false });
});
}
// This is the exact same thing, but in a nested FormRecord. This gives an error.
removeRandomNestedFormControls() {
const subRecord = this.nestedForm.controls.subRecord;
Object.keys(subRecord.controls).forEach((key) => {
if (Math.random() > 0.5) {
return;
}
// The error occurs on the following line
subRecord.removeControl(key, { emitEvent: false });
});
}
我得到的错误是
No overload matches this call.
Overload 1 of 2, '(this: FormGroup<{ [key: string]: AbstractControl<any, any>; }>, name: string, options?: { emitEvent?: boolean | undefined; } | undefined): void', gave the following error.
The 'this' context of type 'FormGroup<{ [key: string]: FormControl<boolean>; }>' is not assignable to method's 'this' of type 'FormGroup<{ [key: string]: AbstractControl<any, any>; }>'.
Type '{ [key: string]: AbstractControl<any, any>; }' is not assignable to type '{ [key: string]: FormControl<boolean>; }'.
'string' index signatures are incompatible.
Type 'AbstractControl<any, any>' is missing the following properties from type 'FormControl<boolean>': defaultValue, registerOnChange, registerOnDisabledChange
Overload 2 of 2, '(name: never, options?: { emitEvent?: boolean | undefined; } | undefined): void', gave the following error.
Argument of type 'string' is not assignable to parameter of type 'never'.
我看到的有趣的事情是我可以毫无问题地使用
addControl()
。另一个有趣的事情(也许是导致此错误的原因)是 formBuilder 似乎将嵌套 FormRecord 的类型更改为 FormGroup。这意味着 subRecord
具有类型 FormRecord<FormControl<boolean>>
,而整个 nestedForm
具有类型
FormGroup<{
field1: FormControl<string>;
subRecord: FormGroup<{ // <-- not FormRecord??
[key: string]: FormControl<boolean>;
}>;
}>
这是 Angular Forms 中的错误,还是我遗漏了一些明显的东西?这应该怎么做?
FormBuild.group
存在推理问题/错误,并且不会返回subRecord
为FormRecord
nestedForm = this.formBuilder.group({
field1: [``],
subRecord: this.formBuilder.record<boolean>({}),
});
推断为
FormGroup<{
field1: FormControl<string>;
subRecord: FormGroup<{
[key: string]: FormControl<boolean>;
}>;
}>
最简单的修复方法是指定
subRecord
的返回类型
const subRecord: FormRecord<FormControl<boolean>> = this.nestedForm.controls.subRecord;