add/remove 动态形成数组项的最佳方法是什么?

What's the best way to add/remove dynamically Form Array item?

以下是我在 CTOR 上将从 API 接收到的数据绑定到我的表单 Group/Array 的方法:

  this.api.getRecipe(id).subscribe((data) => {
    this.form = this.fb.group({
      nome: [data.nome, [Validators.required]],
      ingredienti: this.fb.group({
        acqua: [data.ingredienti.acqua, [Validators.required]],
        farine: this.fb.array(
          data.ingredienti.farine.map(item => (
            this.fb.group({
              quantita: [item.quantita, [Validators.required]],
              nome: [item.nome]
            })
          ))
        )
      })
    });
  });

这就是我在视图中迭代 FormArray's farine 个项目的方式:

  <mat-card *ngFor="let item of form.get('ingredienti').get('farine')['controls']; let itemIndex = index">
    <div [formGroupName]="itemIndex">
      <mat-form-field>
        <input matInput type="number" formControlName="quantita" />
      </mat-form-field>
      <mat-form-field>
        <input matInput type="text" formControlName="nome" />
      </mat-form-field>
    </div>
    <button type="button" (click)="addFarina()">Add</button>
  </mat-card>     

现在,单击 addFarina(),我只想在 FormArray's farine 上添加一个新项目。 我这样做了:

  addFarina() {
    let farineForm = this.form.value.ingredienti.farine;
    let farineFormControls = this.form.get('ingredienti').get('farine')['controls'];

    if (farineForm.length < 4) {
      const farina = this.fb.group({
        quantita: [null, [Validators.required]],
        nome: ['']
      })

      farineForm.push(farina);
      farineFormControls.push(farina);
    }
  } 

但我觉得我并没有真正利用这个框架的潜力,手动更新 this.form 项目和相关的 farine's controls

在表单上“编辑”数据并在 View 上订阅编辑的最佳方式是什么?所以我不需要手动管理数据和视图之间的link。

您应该在 formArray 控件上调用 push 方法。由于您正在将新的 FormGroup 推入普通数组底层 FormGroup 未得到更新。

    addFarina() {
        let farineForm = this.form.value.ingredienti.farine;
        let farineFormControls = this.form.get('ingredienti').get('farine') as FormArray;
    
        if (farineForm.length < 4) {
          const farina = this.fb.group({
            quantita: [null, [Validators.required]],
            nome: ['']
          })
    
          farineFormControls.push(farina);
        }
        console.log(this.form.get('ingredienti').value);
      } 

现在您应该能够像这样访问所有 formValue,无需手动将值推送到数组中。

this.api.addRecipe(this.form.value).subscribe(...)

Working Stackblitz