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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 17:48:19