Angular 5模板驱动表单:按需必填字段的条件验证实现咨询
Angular 5 实现条件必填验证的最简方案
针对你提到的orderNumber输入框仅在orderNumberType下拉框选中非undefined值时才需要必填的需求,Angular 5里有两种超简洁的实现方式,看你平时更习惯用模板驱动还是响应式表单:
方案一:模板驱动表单(代码最少,适合快速实现)
直接给输入框的required属性绑定一个判断表达式就行,逻辑一目了然:
<!-- 下拉选择框 --> <select [(ngModel)]="orderNumberType" name="orderNumberType"> <option value="undefined">请选择订单类型</option> <option value="online">线上订单</option> <option value="offline">线下订单</option> </select> <!-- 订单号输入框,条件触发必填 --> <input type="text" [(ngModel)]="orderNumber" name="orderNumber" [required]="orderNumberType !== 'undefined'" >
只要你选了非默认的类型选项,输入框就会自动开启必填验证;切回默认选项时,必填规则会立刻失效,完全不需要额外写组件逻辑。
方案二:响应式表单(更灵活,适配复杂表单)
如果你的表单本身是响应式的(毕竟你说实际表单比较复杂),推荐用动态调整验证规则的方式,可控性更强:
组件类代码:
import { Component, OnInit } from '@angular/core'; import { FormBuilder, FormGroup, Validators } from '@angular/forms'; @Component({ selector: 'app-order-form', templateUrl: './order-form.component.html' }) export class OrderFormComponent implements OnInit { orderForm: FormGroup; constructor(private fb: FormBuilder) { } ngOnInit() { // 初始化表单,orderNumber初始不设必填 this.orderForm = this.fb.group({ orderNumberType: ['undefined'], orderNumber: [''] }); // 监听订单类型的变化,动态更新验证规则 this.orderForm.get('orderNumberType').valueChanges.subscribe(selectedType => { const orderNumberCtrl = this.orderForm.get('orderNumber'); if (selectedType !== 'undefined') { // 选中有效类型,添加必填验证 orderNumberCtrl.setValidators(Validators.required); } else { // 切回默认选项,清空验证规则 orderNumberCtrl.clearValidators(); } // 必须调用这个方法更新控件状态,否则验证不会生效 orderNumberCtrl.updateValueAndValidity({ emitEvent: false }); }); } }
模板代码:
<form [formGroup]="orderForm"> <select formControlName="orderNumberType"> <option value="undefined">请选择订单类型</option> <option value="online">线上订单</option> <option value="offline">线下订单</option> </select> <input type="text" formControlName="orderNumber"> <!-- 可选:添加错误提示 --> <div *ngIf="orderForm.get('orderNumber').invalid && orderForm.get('orderNumber').touched"> * 订单号不能为空 </div> </form>
小建议
- 如果你的表单逻辑不算特别复杂,方案一绝对是首选,几行模板代码就搞定,完全不用碰组件类;
- 要是表单本身已经用了响应式,或者后续还要加其他复杂验证,方案二更合适,扩展性拉满。
内容的提问来源于stack exchange,提问作者Dallas Caley
相关产品推荐
相关产品推荐

