Angular 2动态嵌套表单

Fir*_*gon 14 forms angular2-forms angular

基本上我想用嵌套对象创建一个动态表单,如下图所示: Angular 2嵌套表单示例

  • 付款是在模型上的阵列中
  • 我们应该能够根据需要添加/取消支付.
  • 表单应同步底层表单控件和模型
  • 支付的数量是任意的,应该从模型中加载到表单中

在Angular 2中我没有找到如何做到这一点的工作示例,尽管在Angular 1中这很容易做到.


以下是我原来的问题,我已经更新了它以便澄清(见上文):

首先,我只是想指出,我知道几天前刚刚发布了新版本的Angular 2 rc.2.因此,创建动态嵌套表单的代码可能已经改变了一些,但是没有足够的文档可以解决这个问题.

在Angular 2的最新版本中(我目前正在使用rc.1但计划更新到rc.2)我需要创建一个这样的表单(伪代码视图):

<form [ngFormModel]="form" (ngSubmit)="onSubmit()">
  <input type="text" ngControl="name">

  <div *ngFor="let expense for expenses; let i = index;" control-group="expenses">
    <input type="text" ngControl="expense.amount" [(ngModel)]="myModel.expenses[i].amount"> 
    <input type="checkbox" ngControl="expense.final" [(ngModel)]="myModel.expenses[i].final"> 
  </div>

  <a class="button" (click)="addExpenseControl()">Add</a>
  <a class="button" (click)="deleteExpenseControl()">Delete</a>
</form>
Run Code Online (Sandbox Code Playgroud)

所以上面的伪代码不起作用,但说实话,因为缺乏文档,我无法弄清楚如何连接这样的东西.有一些关于嵌套ControlGroup的教程,但由于我们需要能够动态添加和删除控制组,所以这不适合这种情况,而且我还需要能够将它们与模型同步.

我发现这个plunkr在这里由Angular团队提供,它允许向表单添加控件 - 但这不是添加/删除ControlGroup,而是使用ControlArray,我不确定这是否适用于此?

我非常熟悉使用较新的基于模型的Angular 2表单,但是我正在掌握资源以便正确地嵌套它们(动态!),并将这些嵌套数据绑定到主表单模型中.我如何在视图中引用嵌套控件?上面的伪代码是否接近?我会从我的控制器发布代码,但说实话,我不知道上面的嵌套费用(ControlGroup ??)从哪里开始......

Fir*_*gon 16

我不得不自己解决这个问题,因为似乎Angular 2中的表单仍然在变化,我没有看到任何其他类似的例子(尽管它看起来像是一个非常常见的用例).

这是使用Angular2 RC3的一个工作示例的插图.

我正在使用本文档中更新的Angular 2表单代码.

app.component.ts(包含表单):

import { Component } from '@angular/core';
import {REACTIVE_FORM_DIRECTIVES, FormControl, FormGroup, FormArray} from '@angular/forms';

@Component({
  selector: 'my-app',
  templateUrl: 'app/app.html',
  directives: [REACTIVE_FORM_DIRECTIVES],
  providers:  []
})
export class AppComponent {
  form: FormGroup;
  myModel:any;

  constructor() {
    // initializing a model for the form to keep in sync with. 
    // usually you'd grab this from a backend API
    this.myModel = {
      name: "Joanna Jedrzejczyk",
      payOffs: [
        {amount: 111.11, date: "Jan 1, 2016", final: false},
        {amount: 222.22, date: "Jan 2, 2016", final: true}
        ]
    }

    // initialize form with empty FormArray for payOffs
    this.form = new FormGroup({
      name: new FormControl(''),
      payOffs: new FormArray([])
    });

    // now we manually use the model and push a FormGroup into the form's FormArray for each PayOff
    this.myModel.payOffs.forEach( 
      (po) => 
        this.form.controls.payOffs.push(this.createPayOffFormGroup(po))
    );
  }

  createPayOffFormGroup(payOffObj) {
    console.log("payOffObj", payOffObj);
    return new FormGroup({
      amount: new FormControl(payOffObj.amount),
      date: new FormControl(payOffObj.date),
      final: new FormControl(payOffObj.final)
    });
  }

  addPayOff(event) {
    event.preventDefault(); // ensure this button doesn't try to submit the form
    var emptyPayOff = {amount: null, date: null, final: false};

    // add pay off to both the model and to form controls because I don't think Angular has any way to do this automagically yet
    this.myModel.payOffs.push(emptyPayOff);
    this.form.controls.payOffs.push(this.createPayOffFormGroup(emptyPayOff));
    console.log("Added New Pay Off", this.form.controls.payOffs)
  }

  deletePayOff(index:number) {
    // delete payoff from both the model and the FormArray
    this.myModel.payOffs.splice(index, 1);
    this.form.controls.payOffs.removeAt(index);
  }
}
Run Code Online (Sandbox Code Playgroud)

请注意,我手动将新的FormGroup对象推送到form.controls.payOffs数组,该数组是一个FormArray对象.

app.html(包含表单html):

  <form (ngSubmit)="onSubmit()" [formGroup]="form">

    <label>Name</label>
    <input type="text" formControlName="name" [(ngModel)]="myModel.name" placeholder="Name">

    <p>Pay Offs</p>
    <table class="simple-table">
      <tr>
        <th>Amount</th>
        <th>Date</th>
        <th>Final?</th>
        <th></th>
      </tr>
    <tbody>
      <tr *ngFor="let po of form.find('payOffs').controls; let i = index">
        <td>
          <input type="text" size=10 [formControl]="po.controls.amount" [(ngModel)]="myModel.payOffs[i].amount">
        </td>
        <td>
          <input type="text" [formControl]="po.controls.date" [(ngModel)]="myModel.payOffs[i].date">
        </td>
        <td>
          <input type="checkbox" [formControl]="po.controls.final" [(ngModel)]="myModel.payOffs[i].final">
        </td>
        <td>
          <button (click)="deletePayOff(i)" style="color: white; background: rgba(255, 0, 0, .5)">x</button>
        </td>
      </tr>
    </tbody>
    <tr>
      <td colspan="4" style="text-align: center; padding: .5em;">
        <button (click)="addPayOff($event)" style="color: white; background: rgba(0, 150, 0, 1)">Add Pay Off</button>
      </td>
    </tr>
    </table>

  </form>
Run Code Online (Sandbox Code Playgroud)

在html表单中,我将表单链接到输入上的模型,语句如下:

... [formControl]="po.controls.amount" [(ngModel)]="myModel.payOffs[i].amount" ...
Run Code Online (Sandbox Code Playgroud)