【问题标题】:Adding rows to form dynamically in Angular 7在Angular 7中动态添加行
【发布时间】:2019-12-10 18:01:49
【问题描述】:

我正在尝试向表单添加行。每行有 3 个输入字段。

这是我到目前为止所做的。

export class MedicationGrid {
   title1:string;
   title2:string;
   title3:string;
}

组件html

  <li class="am-row" *ngFor="let dynamic of dynamicArray; let i = index;">
    <div class="medication-name">
    <input  type="text" class="form-control am-medicine" placeholder="Medicine" [(ngModel)]="dynamicArray[i].title1"  name="medicine" required />
    </div>
   <div class="medication-dosage">
   <input type="text" class="form-control am-dosage" placeholder="Dosage"       [(ngModel)]="dynamicArray[i].title2" name="dosage" />
   </div>
   <div class="medication-frequency">
   <input type="text" class="form-control am-frequency" placeholder="Frequency" [(ngModel)]="dynamicArray[i].title3" name="frequency" />
  </div>
  <div class="medication-add">
   <img src="../../../assets/img/actionModal/add.png" (click)="addMedicationRow(i)"  />
  </div>
 </li>

组件.ts

ngOnInit() {
    this.newDynamic = {title1:"", title2:"", title3:""};
    this.dynamicArray.push(this.newDynamic);
}

addMedicationRow(index) {
   this.newDynamic = {title1:"", title2:"", title3:""};
   this.dynamicArray.push(this.newDynamic);
   return true;
 }

我可以用它添加新行。但问题是,当我在字段中输入一些数据并单击添加按钮时,所有数据都随着新行的插入而消失。我该如何解决这个问题?

【问题讨论】:

标签: angular


【解决方案1】:

您可以使用FormGroupFormControl 创建控件。让我举个例子:

可以看到at stackblitz example

HTML:

<form [formGroup]="myForm">
    <ng-container *ngFor="let group of myForm.controls |keyvalue">
        <div style="margin:20px;" [formGroup]="group.value">
            <label for="">{{group.key}} test</label>
            <input type="text" formControlName="name">
            <button type="button" (click)="onAddMedicine(group.value)">Add Medicine</button>
            <div formArrayName="medicineList">
                <div *ngFor="let item of medicineArray(group.value).controls; let i = index">
                    <label for="">Medicine row</label>
                    <input [formControlName]="i">
          <button (click)="removeMedicine(group.value,i)">remove</button>
      </div>
                </div>
            </div>
    </ng-container>
</form>
<pre>
{{myForm?.value|json}}
</pre>

打字稿:

public myForm: FormGroup;

ngOnInit() {
    this.myForm = new FormGroup({});
    for(let item of ['item1']) {
        this.myForm.addControl(item,
            new FormGroup({
                name: new FormControl(),
                medicineList: new FormArray([])
            })
        )
    } 
} 

onAddMedicine(group:FormGroup) {
    (group.get('medicineList') as FormArray).push(new FormControl())
}

medicineArray(group:FormGroup):FormArray
{
    return group.get('medicineList') as FormArray
}

removeMedicine(group:FormGroup,index:number)
{
    (group.get('medicineList') as FormArray).removeAt(index)
}

【讨论】:

    【解决方案2】:

    本指南完全复制自:https://alligator.io/angular/reactive-forms-formarray-dynamic-fields/

    “所以你有一个表单,并希望从对用户事件的响应中动态添加表单字段?使用 Reactive Forms 和 FormArray 很容易做到。FormArray 有点像 FormGroup,它的使用方式非常相似,不同之处在于它被用作一个数组,包含任意数量的 FormControl、FormGroup 甚至其他 FormArray 实例。"

    导入表单数组

    首先,除了导入其他表单之外,您还需要从 Angular 表单模块导入 FormArray:

    import { FormBuilder, FormGroup, FormArray } from '@angular/forms';
    
    // ...
    

    初始化表单

    现在我们将使用 ngOnInit 钩子中的 FormBuilder 初始化我们的表单。对于这个例子,我们将创建一个允许用户动态添加新项目的订单:

    orderForm: FormGroup;
    items: FormArray;
    
    constructor(private formBuilder: FormBuilder) {}
    
    ngOnInit() {
      this.orderForm = this.formBuilder.group({
        customerName: '',
        email: '',
        items: this.formBuilder.array([ this.createItem() ])
      });
    }
    

    我们的items 实例是一个表单数组而不是一个表单控件,我们正在调用createItem 方法来创建一个表单组作为我们数组中的第一项。这是我们的createItem 方法的样子:

    createItem(): FormGroup {
      return this.formBuilder.group({
        name: '',
        description: '',
        price: ''
      });
    }
    

    动态添加到 FormArray

    现在有趣的部分是,我们可以将 FormArray 视为常规数组并将新项目推入其中:

    addItem(): void {
      this.items = this.orderForm.get('items') as FormArray;
      this.items.push(this.createItem());
    }
    

    现在,当用户单击添加新项目时,只需在模板中调用 addItem 方法即可。

    模板中的FormArray

    最后,我们在模板中使用formArrayName指令绑定到我们的表单数组:

    <div formArrayName="items"
      *ngFor="let item of orderForm.get('items').controls; let i = index;">
      <div [formGroupName]="i">
        <input formControlName="name" placeholder="Item name">
        <input formControlName="description" placeholder="Item description">
        <input formControlName="price" placeholder="Item price">
      </div>
    
      Chosen name: {{ orderForm.controls.items.controls[i].controls.name.value }}
    </div>
    

    注意我们的formGroupName 指令现在如何使用索引而不是名称,并且我们使用ngFor 提供给我们的索引来设置它。

    您还可以通过遍历我们的表单来查看在模板中获取表单控件值的方法。

    【讨论】:

      猜你喜欢
      • 2019-04-26
      • 2021-09-30
      • 2019-11-13
      • 1970-01-01
      • 1970-01-01
      • 2019-09-30
      • 2019-05-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多