Angular的FormArray什么时候是传统数组,什么时候是FormArray对象?

时间:2019-06-10 23:35:33

标签: javascript angular forms formarray

我已经用ControlValueAccessor构建了一个自定义输入组件,并且可以很好地添加标签作为选择。 (Stackblitz

我的问题是:

  1. 当我在表单(城市和州控制)中实现组件时
  2. 通过选择一些选项将值添加到两个控件中
  3. 提交表格
  4. 有时控制值是一组选定标签(如预期的那样)
  5. 其他时候它是一个实际的FormArray对象

这是提交角度形式后的两个相同组件值的屏幕截图。一个是对象数组(预期),另一个是实际的FormArray对象,其.value属性包含对象数组!

enter image description here

如果您不想访问StackBlitz,这是一些工作原理的代码。

自定义控件是这样实现的。

this.form = this.fb.group({
  tags: this.fb.array([])
});

当用户选择下拉菜单项或点击时,将按以下方式保存对象:

get tagsArray(): FormArray { return this.form.get('tags') as FormArray; }
...
this.tagsArray.push(new FormControl(value));
this.onChange(this.tagsArray); // update controller value

您可以通过像这样在我的StackBlitz中的formGroup中实现该组件来复制它(也在我的StackBlitz中):

表单初始化

public form: FormGroup = this.fb.group({
    states: [],
    cities: []
});

模板

<input-tags formControlName="cities" label="Cities" [typeAhead]="cities" [displayKeys]="['name']" filterKeys="['name']"></input-tags>
<input-tags formControlName="states" label="States" [typeAhead]="states" [displayKeys]="['name']" filterKeys="['name']"></input-tags>

但问题是:

什么时候Angular的FormArray是传统数组,什么时候是像对象的FormArray Array?

1 个答案:

答案 0 :(得分:4)

FormArray对象是在使用new FormArray([])formBuilder.array([])创建控件实例时创建的。

但是,如果您使用FormControl方法将ControlValueAccessor实例应用于类,它将写入FormControlFormGroup(如果您想使用Angular表单提供的方法对象)传递给您已传递的控件值。

因此,在第一种情况下,您将获得FormArray对象,在第二种情况下,您将获得常规JS类型(对象,数组,字符串等)或FormGroup / FormControl

如果您想针对自己的情况提供更多的扩展答案,则需要代码示例,因为您的实现有时可能会导致将数组转换为FormArray

更新#1

如果我们将valueChangesusers更改为form,我们会发现这种形式是残破的,因为.value代替了FormArray只是数组。

enter image description here

此外,我已经检查了实现,没有地方可以在其中获得常规数组。但是,自定义控件是错误的IMHO,因为您应该使用.value上的值而不是FormArray或类似的值。

因此,如果您可以更改此控件的实现,则建议您这样做。我用

registerOnChange(fn: any): void {
  this.tagsArray.valueChanges.subscribe(fn);
}