【问题标题】:How to use ReactiveFormsModule and validations for dynamically added controls in Angular?如何在 Angular 中使用 ReactiveFormsModule 和验证来动态添加控件?
【发布时间】:2018-02-02 21:04:33
【问题描述】:

我有几个像这样连接到 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>

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

当我在谷歌上搜索时,我在[(ngModel)] 上获得了很多点击,但我还读到它应该与FormsModule 一起使用,而不是ReactiveFormsModule,正如a blog 中所讨论的那样。

我应该如何处理它?双重绑定 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>

【问题讨论】:

    标签: html forms angular validation typescript


    【解决方案1】:

    您的场景是 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: ''
        });
    

    我的“标签”如下所示:

    我在这些控件中设置默认值,如下所示:

        // 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 在“APM”或“APM - 更新”文件夹中。

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

    【讨论】:

    • 谢谢。这很有帮助,但我仍然有点卡住,因为我试图以不同的方式处理它。我没有明确的模型,只使用private form: FormGroup。所以我需要访问“标签”并在单击添加按钮时向该数组添加一个新组。然而,尝试(this.form.controls.tags as FormArray).??? 并没有产生任何我认为有用的东西。在这种情况下你会怎么做?我已经用新语法更新了问题。
    • 我添加了一个单独的回复,因为它是一个不同的答案。希望有帮助。如果没有,也许您可​​以创建一个 plunker 来展示您正在尝试做的更多事情。
    【解决方案2】:

    如果你只是想让这段代码工作,你只需要把它改成一个数组:

    <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。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-06-18
      • 1970-01-01
      • 1970-01-01
      • 2018-07-20
      • 2016-02-07
      • 2010-09-29
      • 1970-01-01
      相关资源
      最近更新 更多