You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular Reactive Forms用FormArray实现套餐SIM卡选择校验求助

功能需求

我想要实现如下功能:
我有一份可供订阅的套餐列表,数据结构如下:

{ id: 1, data: '1GB', minsms: '5.000', value: 7.5, simCards: 1 },
{ id: 2, data: '3GB', minsms: '5.000', value: 10, simCards: 3 },
{ id: 3, data: '10GB', minsms: '5.000', value: 15, simCards: 2 },
{ id: 4, data: '20GB', minsms: '5.000', value: 20, simCards: 1 },

客户可以选择每个套餐对应的SIM卡购买数量,我需要添加校验规则:即便客户选择0张卡也必须完成选择操作,不能为空。我尝试使用FormArray实现该功能但遇到了阻碍。

实现方案
  • 表单初始化时,给每个套餐对应生成一个带Validators.required校验的FormControl,统一放到FormArray中管理。这里的必填校验只会拦截空值,用户输入0时属于合法值,校验会直接通过,刚好匹配需求。

示例TypeScript代码:

import { Component } from '@angular/core';
import { FormBuilder, FormGroup, FormArray, FormControl, Validators } from '@angular/forms';

@Component({
  selector: 'app-package-select',
  templateUrl: './package-select.component.html'
})
export class PackageSelectComponent {
  // 套餐列表
  packages = [
    { id: 1, data: '1GB', minsms: '5.000', value: 7.5, simCards: 1 },
    { id: 2, data: '3GB', minsms: '5.000', value: 10, simCards: 3 },
    { id: 3, data: '10GB', minsms: '5.000', value: 15, simCards: 2 },
    { id: 4, data: '20GB', minsms: '5.000', value: 20, simCards: 1 },
  ];

  packageForm: FormGroup;

  constructor(private fb: FormBuilder) {
    // 为每个套餐生成对应的表单控件,添加必填校验
    const simCountControls = this.packages.map(() => 
      new FormControl(null, Validators.required)
    );
    this.packageForm = this.fb.group({
      simCounts: new FormArray(simCountControls)
    });
  }

  // 快捷获取FormArray实例
  get simCounts(): FormArray {
    return this.packageForm.get('simCounts') as FormArray;
  }

  // 提交表单处理逻辑
  onSubmit() {
    if (this.packageForm.valid) {
      // 按顺序对应每个套餐的购买数量
      const selectedCounts = this.simCounts.value;
      const result = this.packages.map((pkg, index) => ({
        ...pkg,
        buyCount: selectedCounts[index]
      }));
      // 后续处理result即可
      console.log(result);
    }
  }
}

模板示例代码:

<form [formGroup]="packageForm" (ngSubmit)="onSubmit()">
  <div *ngFor="let pkg of packages; let i = index" style="margin: 12px 0;">
    <p>套餐{{i+1}}:{{pkg.data}},月费{{pkg.value}}元</p>
    <input 
      type="number" 
      min="0" 
      [formControl]="simCounts.at(i)"
      placeholder="请输入SIM卡购买数量"
      style="padding: 4px 8px;"
    >
    <span 
      *ngIf="simCounts.at(i).touched && simCounts.at(i).invalid"
      style="color: red; margin-left: 8px;"
    >
      请填写数量,可填0
    </span>
  </div>
  <button type="submit" [disabled]="packageForm.invalid" style="padding: 6px 12px;">
    提交选择
  </button>
</form>

内容的提问来源于stack exchange,提问作者Rafael Vieira de Oliveira

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 13:09:05