响应式表单:如何在 Angular 7/8/9 稍后的时间点将新的 FormGroup 或 FormArray 添加到现有的 FormGroup

Reactive Forms: How to add new FormGroup or FormArray into an existing FormGroup at a later point in time in Angular 7/8/9

在 Whosebug 的其他示例中,有很多关于在 FormArrays 中使用 FormGroups 的问题。但是我的问题恰恰相反。

FormArrays 有一个 push 方法,这使得很多事情成为可能。 FormGroups 确实有一个 addControl 方法来添加简单的 FormControls。 AFAIK FormGroups 没有 addFormArrayaddFormGroup 方法。所以我需要你的帮助。

以下情况:

this.myForm = this.fb.group({
  id: this.fb.control([this.book.id]),
  // or short form `id: [this.book.id],`
});

稍后添加一个简单的控件很容易:

this.myForm.addControl('isbn', this.fb.control(this.book.isbn));

但是如何将 FormArrays 和 FormGroups 添加到现有的 FormGroup 中呢?例如,我想为此目的使用以下数组和对象:

const authors  = ['George Michael', 'Aretha Franklin'];
const metaData = { description : 'Great Book', publication: 2019}

我想添加 authorsArraymetaData 只有在它们存在的情况下。这就是为什么我想稍后添加它们的原因。

p.s。请忽略验证规则。

FormGroup addControl 方法接受 AbstractControl 作为参数,参数可以是 FormControlFormArray 或另一个 FormGroup 因为它们全部扩展 AbstractControl.

class FormGroup extends AbstractControl {}

class FormControl extends AbstractControl {}

class FormArray extends AbstractControl {}

FormBuilder 可以帮助您使用 array()group() 方法构建此类控件:

this.myForm = this.fb.group({
  id: this.fb.control([this.book.id]),
  authors: this.fb.array(['George Michael', 'Aretha Franklin']),
  metaData: this.fb.group({ description : 'Great Book', publication: 2019})
});

之后您仍然可以使用工厂来构建您需要的控件(无论是哪种控件):

this.myForm.addControl('authors',
                       this.fb.array(['George Michael', 'Aretha Franklin']))
this.myForm.addControl('metaData',
                       this.fb.group({description: 'Great Book', publication: 2019}))

您可以简单地传递 FormArray 而不是 FormControl

this.form.addControl('arr',this.fb.array([]));

编辑:使用现有值

要使用 authors 数组中的值,请使用:

authors.forEach(author => {
  (<FormArray>this.form.controls.arr).push(new FormControl(author));
});

this.myForm.addControl('authors', this.fb.array(['George Michael', 'Aretha Franklin']))