Angular 5条件必填textarea问题:取消复选框后仍必填
Angular 5: 取消复选框后Textarea仍强制必填的问题解决
你碰到的这个问题其实是Angular表单和*ngIf交互的典型坑——当*ngIf把mat-form-field从DOM中移除时,表单组里对应的FormControl并没有同步更新它的验证规则。
你原来的写法里,[required]绑定只在textarea存在于DOM的时候生效,一旦取消复选框,*ngIf把元素删掉,这个绑定就再也不会触发变化检测了,导致表单里的otherVendors控件还保留着之前添加的必填验证,所以即使你看不到textarea,表单依然会判定它是必填项。
下面给你两种靠谱的解决方案,推荐第一种:
方案1:动态添加/移除验证器(最规范的做法)
我们直接在组件类里监听otherVendorsChecked的变化,手动给otherVendors控件添加或移除必填验证,这样不管DOM元素是否存在,表单的验证规则都会同步更新。
首先调整组件类的代码:
import { Component, OnInit, OnChanges, SimpleChanges } from '@angular/core'; import { FormGroup, FormControl, Validators } from '@angular/forms'; export class YourComponent implements OnInit, OnChanges { otherVendorsChecked: boolean = false; form: FormGroup; // 假设你的lastFacilityDetailOfCalendarEvent已经定义 lastFacilityDetailOfCalendarEvent: any; ngOnInit() { this.form = new FormGroup({ otherVendors: new FormControl('', [Validators.minLength(2)]), // 这里放你的其他表单控件 }); this.fillForm(); } // 监听otherVendorsChecked的变化 ngOnChanges(changes: SimpleChanges) { if (changes['otherVendorsChecked']) { const otherVendorsCtrl = this.form.get('otherVendors'); if (!otherVendorsCtrl) return; if (this.otherVendorsChecked) { // 勾选复选框时,添加必填验证 otherVendorsCtrl.addValidators(Validators.required); } else { // 取消勾选时,移除必填验证 otherVendorsCtrl.removeValidators(Validators.required); } // 必须更新控件状态,否则新的验证规则不会生效 otherVendorsCtrl.updateValueAndValidity({ emitEvent: false }); } } fillForm() { const otherVendorsValue = this.lastFacilityDetailOfCalendarEvent?.otherVendors || ''; this.form.controls['otherVendors'].setValue(otherVendorsValue); if (otherVendorsValue && otherVendorsValue.length > 0) { this.otherVendorsChecked = true; } } }
然后简化模板代码,不需要再在textarea上绑定[required]了:
<div> <mat-checkbox [ngModelOptions]="{standalone: true}" [(ngModel)]="otherVendorsChecked">Other option:</mat-checkbox> </div> <mat-form-field *ngIf="otherVendorsChecked"> <textarea matInput formControlName="otherVendors"></textarea> </mat-form-field>
方案2:用[hidden]替代*ngIf(适合简单场景)
如果你不想修改表单验证逻辑,也可以把*ngIf换成[hidden]——[hidden]只是把元素设为不可见,不会从DOM中移除,这样[required]的绑定就能一直生效:
<div> <mat-checkbox [ngModelOptions]="{standalone: true}" [(ngModel)]="otherVendorsChecked">Other option:</mat-checkbox> </div> <mat-form-field [hidden]="!otherVendorsChecked"> <textarea matInput formControlName="otherVendors" [required]="otherVendorsChecked"></textarea> </mat-form-field>
不过这个方案有个小缺点:元素依然在DOM里,只是隐藏了,可能会有一些不必要的渲染开销,所以更推荐方案1。
内容的提问来源于stack exchange,提问作者quma
相关产品推荐
相关产品推荐

