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
相关产品推荐
相关产品推荐

