Angular12 FormArray如何为复选框添加限制仅可选中一条当前任职记录
实现方案
核心思路
当某条工作经历的「当前任职」复选框被勾选时,自动取消其他所有经历的勾选状态,你可以通过监听表单控件值变化实现该逻辑。
第一步:组件类逻辑改造
在新增工作经历FormGroup时订阅current控件的数值变化事件,触发勾选时遍历FormArray重置其余条目的勾选状态:
import { Component, OnInit, OnDestroy } from '@angular/core'; import { FormArray, FormBuilder, FormGroup, Validators, FormControl } from '@angular/forms'; import { takeUntil } from 'rxjs/operators'; import { Subject } from 'rxjs'; @Component({ selector: 'app-work-experience', templateUrl: './work-experience.component.html', styleUrls: ['./work-experience.component.scss'] }) export class WorkExperienceComponent implements OnInit, OnDestroy { workForm: FormGroup; // 用于销毁订阅避免内存泄漏 private destroy$ = new Subject<void>(); constructor(private fb: FormBuilder) {} ngOnInit(): void { // 初始化根表单 this.workForm = this.fb.group({ experiences: this.fb.array([]) }); // 默认新增一条空白经历 this.addExperience(); } // 快速获取工作经历FormArray get experiences(): FormArray { return this.workForm.get('experiences') as FormArray; } // 新增工作经历方法 addExperience(): void { const expGroup = this.fb.group({ company: ['', Validators.required], position: ['', Validators.required], startDate: ['', Validators.required], endDate: [''], current: [false] }); // 监听当前条目的current复选框变化 expGroup.get('current').valueChanges .pipe(takeUntil(this.destroy$)) .subscribe(isChecked => { // 只有当前是勾选状态时才触发重置其他条目的逻辑 if (isChecked) { this.experiences.controls.forEach(item => { // 跳过当前正在操作的条目,加上emitEvent: false避免循环触发订阅 if (item !== expGroup) { item.get('current').setValue(false, { emitEvent: false }); } }); } }); this.experiences.push(expGroup); } ngOnDestroy(): void { this.destroy$.next(); this.destroy$.complete(); } }
第二步:HTML模板无需额外改造
原有模板绑定逻辑保持不变即可,参考示例:
<form [formGroup]="workForm"> <div formArrayName="experiences"> <div *ngFor="let item of experiences.controls; let i=index" [formGroupName]="i"> <!-- 其他表单字段省略 --> <mat-checkbox formControlName="current">当前任职</mat-checkbox> </div> </div> <button mat-button type="button" (click)="addExperience()">添加新经历</button> </form>
可选增强:添加FormArray全局校验
如果需要在表单提交时做二次校验,可添加自定义校验器:
// 自定义校验规则:最多只能有一个当前任职 function singleCurrentValidator(arr: FormArray) { const checkedNum = arr.controls.filter(item => item.get('current').value).length; return checkedNum > 1 ? { multipleCurrent: true } : null; } // 初始化表单时绑定校验器 this.workForm = this.fb.group({ experiences: this.fb.array([], [singleCurrentValidator]) });
内容的提问来源于stack exchange,提问作者mikefolu
相关产品推荐
相关产品推荐

