具有自由形式对象的Angular反应形式数组

时间:2020-08-29 07:01:55

标签: javascript angular angular-material angular-reactive-forms

我已经与Angular一起工作了一段时间,我对Reactive表单和模板驱动的表单了解得很清楚,但是我遇到了这个问题,尤其是Angular的Reactive Form Array。

我希望POST / PUT发送到的

API响应是这样形成的,用户可以在其中添加一行,而下拉菜单将让他们选择属性,在这种情况下,它是“ p”,“ h1”, “ h2”,以此类推,以及他们希望输入的值

  "description": {
"body": [
  {
    "p": "test paragraph"
  },
  {
    "h1": "test header"
  }
],

我正在将旧的JQuery和js废话转换为Framework,对我而言,很难下定决心如何转换此过程。

用户将点击添加项目:
enter image description here

然后我会假设通过 formArray 创建一行,因为我已经尝试过了,并且行了,但是编辑属性的下拉菜单给了我一个问题。

enter image description here

这就是创建另外几行时的样子 enter image description here

我通过以下示例了解formArrays的工作方式:
Dynamically Add Rows Based on Condition Using Reactive Forms in Angular

所以我将需要一个吸气剂,以及用于创建动态表单和HTML的函数,但目前我仍然处于困境。

1 个答案:

答案 0 :(得分:0)

我最终解决了大部分问题, 我们将使用Angular的FormBuilder,FormArrays和模板插值。

首先使用表单构建器定义表单:

text-form.ts

  this.textForm = this.fb.group({
  lang: null,
  description: this.fb.array([]),
});

在这种情况下,您将使用Angular的getter来从上面定义的表单构建器中获取描述

  get descriptionItems() {
    return this.artifactTextForm.get('description') as FormArray;
  }

然后,您将创建两个函数,一个用于按钮中的添加行,另一个用于删除数组中索引的当前行

这将与其他示例有所不同,因为我们将使用一些ES6技巧

  addDescriptionItem() {
this.descriptionItems.push(this.fb.group({[this.selectedHeading]: ''}));
}

我将 this.selectedHeading 定义为: 在我的组件类的顶部

  selectedHeading = 'h1';

现在创建将在模板的forloop中为每一行创建的按钮

      // deleteDescriptionItem removes the item at the index given in the formArray
  deleteDescriptionItem(index: number) {
    this.descriptionItems.removeAt(index);
  }

现在是模板中最重要的部分之一,可确保一切看起来不错。我正在使用角度材料设计,但它应该可以正常工作并在本地执行相同的操作。

    <form [formGroup]="artifactTextForm">

  <mat-dialog-content>

    <mat-form-field appearance="fill">
      <mat-label>Select Header Type</mat-label>
      <mat-select [(value)]="selectedHeading">
        <mat-option value="h1">Header 1</mat-option>
        <mat-option value="h2">Header 2</mat-option>
        <mat-option value="h3">Header 3</mat-option>
        <mat-option value="h4">Header 4</mat-option>
        <mat-option value="p">Paragraph</mat-option>
      </mat-select>
    </mat-form-field>

    <!-- Description form array -->
    <div formArrayName="description">
      <div *ngFor="let item of descriptionItems.controls; let i = index" [formGroupName]="i">
        <input
          [formControlName]="this.selectedHeading"
          placeholder="Enter Description Data"
          [maxLength]="formMaxLength">
        <button
          mat-raised-button
          color="primary"
          type="button"
          (click)="deleteDescriptionItem(i)">Delete Item</button>
      </div>
      <button mat-raised-button color="primary" type="button" (click)="addDescriptionItem()">Add Description</button>
    </div>
  </mat-dialog-content>

  <mat-dialog-actions>
    <button mat-raised-button type="submit" (click)="onSubmit()">Save</button>
    <button mat-raised-button type="reset" (click)="dialogRef.close()">Cancel</button>
  </mat-dialog-actions>
</form>

确保添加按钮位于带有forloop的div之外,并且应该像这样。

enter image description here

旁注: 在ubuntu上射出的火焰真是太神奇了。

相关问题