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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 04:21:03