Angular13响应式表单校验不通过时如何阻止空数据插入数据库
问题根因
校验提示正常显示但空数据依然提交的核心原因:onSubmit方法中仅设置了validate = true控制错误提示显隐,没有加表单有效性判断就直接调用提交接口,无论表单是否符合规则都会执行提交逻辑。
另外还有4个隐藏问题:
- 编辑场景下
ngOnChanges直接读取changes['data'].currentValue调用setValue,新增场景data输入为null时会直接触发空指针报错 - 隐藏域
createby直接在模板写value属性不符合响应式表单规范,值不会被FormControl正确接管 - 下拉选择框默认选项未设置空值,会导致初始状态校验逻辑异常
- 给number类型的
priority配置的Validators.maxLength(255)无效,该校验器仅针对字符串长度生效,数字大小限制需要用Validators.max(255)
修复步骤
1. 修正组件TS逻辑,增加表单有效性拦截
修改gender.add.component.ts,提交前先判断表单状态,不合法直接中断提交;修复空值报错问题,将固定值直接初始化到表单中,不要提交时临时修改。修正后核心代码如下:
genderData: FormGroup; gender: any = []; validate: boolean = false; @Output() submitted = new EventEmitter<boolean>(); @Input() get data(): any { return this._data; } set data(data: any) { this._data = data || null; } private _data: gender; constructor(private fb: FormBuilder, private genderService: GenderService) { // 固定值直接在表单初始化时赋值,无需提交时临时修改 this.genderData = this.fb.group({ id: [''], genderid: ['', Validators.required], // 数字类型改用max校验限制最大值 priority: ['', [Validators.required, Validators.max(255)]], createby: ['0x0E1DA7C4F8F9FAE2C9A4A59528FF91DC400CB152B497C05E8491610E42092C9F', Validators.required], }); } ngOnInit(): void { this.genderService.getAssociativeData().subscribe((response: any) => { this.gender = response; }); } onSubmit() { this.validate = true; // 核心拦截逻辑:表单无效直接返回,不执行后续提交 if (this.genderData.invalid) { return; } const data = this.genderData.value; this.genderService.addNewGender(data).subscribe((response) => { // 提交成功后重置表单状态 this.validate = false; this.genderData.reset({ id: '', createby: '0x0E1DA7C4F8F9FAE2C9A4A59528FF91DC400CB152B497C05E8491610E42092C9F' }); this.submitted.emit(true); }); } ngOnChanges(changes: SimpleChanges) { // 无编辑数据时重置为新增状态,避免空指针报错 if (!changes['data']?.currentValue) { this.genderData.reset({ id: '', genderid: '', priority: '', createby: '0x0E1DA7C4F8F9FAE2C9A4A59528FF91DC400CB152B497C05E8491610E42092C9F' }); this.validate = false; return; } const formData = changes['data'].currentValue; // 编辑场景用patchValue赋值,无需强制匹配所有字段 this.genderData.patchValue({ id: formData.ID, genderid: formData.Gender, priority: formData.Priority, createby: formData.CreateBy, }); } get f():{[key: string]: AbstractControl}{ return this.genderData.controls; }
2. 修正表单模板写法
修改gender.add.component.html,去掉响应式表单控件上多余的value属性,给下拉默认选项加空值,改用表单ngSubmit事件处理提交:
<form class="new-added-form" [formGroup]="genderData" (ngSubmit)="onSubmit()"> <input type="hidden" formControlName="id"> <input type="hidden" formControlName="createby"> <div class="row"> <div class="col-12"> <div class="mb-3"> <label for="lblgenderID" class="form-label">Subject:</label> <!-- 默认选项加value="",确保未选择时能触发required校验 --> <select formControlName="genderid" class="form-control" id="gender" [ngClass]="{'is-invalid':validate && f['genderid'].errors}"> <option value="" disabled>Select Subject</option> <option *ngFor="let list of gender" [value]="list.GenderID">{{list.GenderName}}</option> </select> <div *ngIf="validate && f['genderid'].errors" class="invalid-feedback"> <div *ngIf="f['genderid'].errors['required']">Subject is required</div> </div> </div> <div class="mb-3"> <label for="lblPriority" class="form-label">Priority:</label> <input type="number" formControlName="priority" class="form-control" id="chapter_priority" [ngClass]="{'is-invalid': validate && f['priority'].errors}"> <div *ngIf="validate && f['priority'].errors" class="invalid-feedback"> <div *ngIf="f['priority'].errors['required']">Priority is required</div> <div *ngIf="f['priority'].errors['max']">Priority can not larger than 255</div> </div> </div> <!-- 按钮改为submit类型,配合表单ngSubmit事件 --> <button type="submit" class="btn btn-primary">Submit</button> </div> </div> </form>
3. 修复列表页新增/编辑切换的数据残留
修改gender.list.component.ts,点击新增按钮打开弹窗前清空编辑数据:
openAddModal() { this.editData = null; $('#exampleModal').modal('show'); }
对应修改gender.list.component.html的新增按钮,绑定点击事件:
<button class="btn btn-primary btn-lg" (click)="openAddModal()" data-bs-toggle="modal" data-bs-target="#exampleModal">Add New</button>
修复效果
修改完成后,点击提交时如果存在未填的必填项,只会显示校验错误提示,不会向后端发送提交请求;只有所有校验规则全部通过后,才会调用接口提交数据,同时解决了新增/编辑切换时数据残留、空值报错、数字校验无效的问题。
内容的提问来源于stack exchange,提问作者Mayank
相关产品推荐
相关产品推荐

