如果在FormArray为空时尝试设置FormArray值:
const array1 = new FormArray([]);
array1.setValue(['']);
我收到此错误:
尚未向该数组注册任何表单控件。如果您使用的是ngModel,则可能要检查下一个勾号
如果在1时加2,
const array2 = new FormArray([new FormControl('')]);
array2.setValue(['', '']);
我收到以下错误:
在索引1处找不到表单控件
如果我尝试将2设置为1,则
const array3 = new FormArray([new FormControl(''), new FormControl('')]);
array3.setValue(['']);
我收到以下错误:
必须在索引:1处提供用于表单控制的值。
问题:如何编写一个可以用任意长度的列表更新表单数组的值的函数?
StackBlitz:https://stackblitz.com/edit/angular-wduzv9?file=src/app/app.component.ts
* edit我了解可以使用push()
,at()
和removeAt(0)
方法。我在寻找通用功能。它可以使用您想要的任何方法。
您可以初始化一个空的formArray,然后添加控件,然后设置值,
const arr = new FormArray([]);
const a = new FormControl('a', []);
const b = new FormControl('b', []);
const c = new FormControl('c', []);
arr.push(a);
arr.push(b);
arr.push(c);
console.log(arr.value); // ["a", "b", "c"]
// arr.setValue([0]);
console.log(arr)
arr.controls[0].setValue('xxx')
console.log(arr.value); // "xxx", "b", "c"
问题是,在不知道要在新索引的AbstractControl
中使用哪种类型的FormArray
的情况下,无法在新键或索引处添加新值。
任何解决方案都必须考虑到该索引应该是FormControl
,FormGroup
还是FormArray
,因此我在toSubControl
函数中提供了setFormArrayValue
参数。 (我还提供了一些示例值来提供给此参数。)
我选择删除所有项目,然后为每个值添加新控件。试图保留已经存在的控件会产生一些奇怪的行为。
这是我想出的解决方案:
export function setFormArrayValue<T>(
array: FormArray,
values: T[],
toSubControl: (values: T) => AbstractControl = toFormControl
) {
while (array.length) {
array.removeAt(0);
}
values
.map(toSubControl)
.forEach(function(control) {
array.push(control);
});
return array;
}
function toFormControl(value) {
return new FormControl(value)
}
function toFormGroup(value) {
const fields = Object.entries(value).reduce(function(hash, [key, value]) {
hash[key] = new FormControl(value);
return hash;
}, {})
return new FormGroup(fields);
}
function toFormGroup(value) {
const fields = Object.entries(value).reduce(function(list, [key, value]) {
return list.concat([new FormControl(value)]);
}, [])
return new FormGroup(fields);
}