MST
星途 面试题库

面试题:Angular响应式表单中如何实现动态添加和移除表单控件并保持验证功能

假设你正在开发一个订单管理系统,订单中的商品项数量不确定,需要在前端使用Angular响应式表单实现动态添加和移除商品项的表单控件,且每个商品项都有价格、数量等必填和格式验证要求。请描述实现思路,并给出关键代码片段。
34.6万 热度难度
前端开发Angular

知识考点

AI 面试

面试题答案

一键面试

实现思路

  1. 创建响应式表单:使用 FormGroupFormArray 来构建表单结构。FormGroup 用于整个订单表单,FormArray 用于存储动态的商品项。
  2. 动态添加和移除商品项:通过在组件类中定义方法,操作 FormArray 来实现商品项的添加和移除。
  3. 表单验证:为每个商品项的价格、数量等字段添加验证器,确保数据的必填和格式正确。
  4. 模板绑定:在HTML模板中,使用 *ngFor 指令循环渲染商品项表单控件,并处理添加和移除按钮的点击事件。

关键代码片段

  1. 组件类(.ts文件)
import { Component } from '@angular/core';
import { FormGroup, FormArray, FormControl, Validators } from '@angular/forms';

@Component({
  selector: 'app-order-form',
  templateUrl: './order-form.component.html',
  styleUrls: ['./order-form.component.css']
})
export class OrderFormComponent {
  orderForm: FormGroup;

  constructor() {
    this.orderForm = new FormGroup({
      items: new FormArray([this.createItem()])
    });
  }

  createItem(): FormGroup {
    return new FormGroup({
      price: new FormControl('', [Validators.required, Validators.pattern('^[0-9]+(\.[0-9]{1,2})?$')]),
      quantity: new FormControl('', [Validators.required, Validators.min(1)])
    });
  }

  get items(): FormArray {
    return this.orderForm.get('items') as FormArray;
  }

  addItem() {
    this.items.push(this.createItem());
  }

  removeItem(index: number) {
    this.items.removeAt(index);
  }
}
  1. 模板(.html文件)
<form [formGroup]="orderForm">
  <div formArrayName="items">
    <div *ngFor="let item of items.controls; let i = index">
      <div [formGroupName]="i">
        <label for="price">价格:</label>
        <input type="text" formControlName="price" id="price">
        <div *ngIf="items.controls[i].get('price').hasError('required') && (items.controls[i].get('price').touched || items.controls[i].get('price').dirty)">
          价格是必填项
        </div>
        <div *ngIf="items.controls[i].get('price').hasError('pattern') && (items.controls[i].get('price').touched || items.controls[i].get('price').dirty)">
          价格格式不正确,最多两位小数
        </div>

        <label for="quantity">数量:</label>
        <input type="number" formControlName="quantity" id="quantity">
        <div *ngIf="items.controls[i].get('quantity').hasError('required') && (items.controls[i].get('quantity').touched || items.controls[i].get('quantity').dirty)">
          数量是必填项
        </div>
        <div *ngIf="items.controls[i].get('quantity').hasError('min') && (items.controls[i].get('quantity').touched || items.controls[i].get('quantity').dirty)">
          数量至少为1
        </div>

        <button type="button" (click)="removeItem(i)">移除</button>
      </div>
    </div>
    <button type="button" (click)="addItem()">添加商品项</button>
  </div>
</form>