如何在Angular中使用ReactiveFormsModule和验证来动态添加控件?

时间:2017-08-24 21:00:30

标签: html forms angular validation typescript

我有几个字段连接到FormBuilder就像这样。

constructor(private builder: FormBuilder) {
  this.form = builder.group({
    "firstName": [...],
    "lastName": [...]
  });
}

在标记中,除了修复控件之外,我还会有一个未知数量的输入框。它从零开始,可以增加,因为用户点击一个按钮,每次点击都会添加一个新的输入框。每个输入框都会有一个删除按钮,因此它们的数量是完全动态的。

<div class="input-caption">FirstName</div>
<input type="text" formControlName="firstName">

<div class="input-caption">LastName</div>
<input type="text" formControlName="lastName">

<div id="options"></div>
<button (click)="addOption()">Add option</button>

由于需要验证动态添加的字段,我觉得我需要在组定义中声明它们。我不知道怎么样。

当我用Google搜索时,我在[(ngModel)]上获得了大量点击,但我也读到它应该与FormsModule一起使用,而不是a blog中讨论的ReactiveFormsModule }。

我该如何接近它?双重绑定 ngModel 是唯一的选择吗?

根据答案

修改

HTML

<div *ngFor="let tag of []; let i = index;" [formGroupName]="i">
  <div class="input-caption">Tag</div>
  <input formControlName="name"> -->
</div>

TS

constructor(private builder: FormBuilder) {
  this.form = builder.group({
    "firstName": [...],
    "lastName": [...],
    "tags": this.builder.array([]),
  });
}

addTag(): void {
  (this.form.controls.tags as FormArray).???;
}

我还尝试在标记中指定一个硬编码数组,如下所示,但没有看到任何控件被渲染。

<div *ngFor="let tag of [{'name':'uno'},{'name':'duo'}]; let i = index;" 
     [formGroupName]="i">
  <div class="input-caption">Tag</div>
  <input formControlName="name"> -->
</div>

2 个答案:

答案 0 :(得分:2)

您的方案是FormArray的目的。请参阅此处的文档:https://angular.io/guide/reactive-forms#use-formarray-to-present-an-array-of-formgroups

文档显示了一组FormGroups,但您也可以使用它来创建FormControls数组。

以下是我的申请中的一个例子:

    this.productForm = this.fb.group({
        productName: ['', [Validators.required,
                           Validators.minLength(3),
                           Validators.maxLength(50)]],
        productCode: ['', Validators.required],
        starRating: ['', NumberValidators.range(1, 5)],
        tags: this.fb.array([]),
        description: ''
    });

我的&#34;标签&#34;看起来像这样:

enter image description here

我将默认值设置为这些控件:

    // Update the data on the form
    this.productForm.patchValue({
        productName: this.product.productName,
        productCode: this.product.productCode,
        starRating: this.product.starRating,
        description: this.product.description
    });
    this.productForm.setControl('tags', this.fb.array(this.product.tags || []));

您可以在此处找到我的示例代码:https://github.com/DeborahK/Angular2-ReactiveForms在&#34; APM&#34;或者&#34; APM - 更新了&#34;文件夹。

这是Pluralsight课程的代码:Angular Reactive Forms此处:https://app.pluralsight.com/library/courses/angular-2-reactive-forms/table-of-contents

答案 1 :(得分:0)

如果您只想使用此代码,则只需将其更改为数组:

<div *ngFor="let tag of ['uno','duo']; let i = index;" 
     [formGroupName]="i">
  <div class="input-caption">{{ tag }}</div>
  <input formControlName="name"> -->
</div>

他们并不需要成为团队。如果它们不是:

,它可能会更简单
<div *ngFor="let tag of ['uno','duo']">
  <div class="input-caption">{{ tag }}</div>
  <input [formControlName]="tag"> -->
</div>

如果这就是你所需要的......那么你甚至不需要FormArrays。