Angular的FormArray什么时候是传统数组,什么时候是FormArray对象? [英] When is Angular's FormArray a traditional array and when is it a FormArray object?

查看:160
本文介绍了Angular的FormArray什么时候是传统数组,什么时候是FormArray对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I've built a custom input component with ControlValueAccessor and it works great to add tags as selections. (Stackblitz)

我的问题是:

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

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

Here is a screenshot of two of the same component's values after submitting the angular form. One is an array of objects (expected) the other is an actual FormArray object which .value property contains the array of objects!

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

Here is some code of how it works in case you don't want to visit StackBlitz.

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

The custom control is implemented like this.

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

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

When the user selects a dropdown item or hits enter the object is saved like this:

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中):

You could replicate this by implementing the component in my StackBlitz in a formGroup just like this (also in my 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?

推荐答案

FormArray对象.

但是,如果将FormControl实例应用于具有ControlValueAccessor方法的类,则会将FormControlFormGroup(如果要使用Angular表单对象提供的)写入控件的值已经过去了.

However, if you apply a FormControl instance to class with ControlValueAccessor methods it will write either FormControl or FormGroup (if you want to work with provided by Angular form objects) to the value of control you have passed.

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

Thus, in first case you get a FormArray object and in second case you can get either regular JS types (object, array, string etc.) or FormGroup/FormControl.

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

If you want more expanded answer specific to your case the code sample is required because your implementation may cause transforming array to FormArray at some point.

如果将valueChangesusers更改为form,则可以看到这种形式已损坏,因为.value给了我们另一个FormArray而不是数组.

If we change a valueChanges from users to form we can see that this form is kind of broken, because .value gives us another FormArray instead of just Array.

此外,我已经检查了实现,没有地方可以在那里找到常规数组.但是,自定义控件是用错误的恕我直言实现的,因为您应该将.value上的值而不是FormArray或类似的值.

Also, I've checked the implementation and there is nowhere you can get regular array in there. However, custom control is implemented wrong IMHO, since you should the value on .value instead of FormArray or whatever similar to this.

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

Therefore, if you can change the implementation of this control I would suggest you do that. I do it in way of

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

这篇关于Angular的FormArray什么时候是传统数组,什么时候是FormArray对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆