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

Ben*_*cot 12 javascript forms angular formarray

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

我的问题是:

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

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

在此处输入图片说明

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

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

this.form = this.fb.group({
  tags: this.fb.array([])
});
Run Code Online (Sandbox Code Playgroud)

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

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

您可以像这样在我的StackBlitz中的formGroup中实现该组件(也在我的StackBlitz中):

表格初始化

public form: FormGroup = this.fb.group({
    states: [],
    cities: []
});
Run Code Online (Sandbox Code Playgroud)

模板

<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>
Run Code Online (Sandbox Code Playgroud)

但问题是:

Angular的FormArray什么时候是传统数组,什么时候像Object一样的FormArray Array?

Ser*_*gey 3

FormArraynew FormArray([])当您使用或创建控件实例时,正在创建对象formBuilder.array([])

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

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

如果您想要针对您的情况进行更多扩展答案,则需要代码示例,因为您的实现可能会导致FormArray在某个时刻将数组转换为。

更新#1

如果我们将valueChangesfromusers改为 ,form我们可以看到这种形式有点被破坏,因为.value它给了我们另一个FormArray而不只是数组。

在此输入图像描述

另外,我已经检查了实现,并且没有任何地方可以在那里获取常规数组。但是,恕我直言,自定义控件的实现是错误的,因为您应该使用 on 的值.value来代替FormArray或与此类似的值。

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

registerOnChange(fn: any): void {
  this.tagsArray.valueChanges.subscribe(fn);
}
Run Code Online (Sandbox Code Playgroud)