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

如何在mdbootstrap Angular.js表单中手动标记输入项为无效状态?

问题核心原因

你的问题是三个错误叠加导致的:

  1. 自定义mustMatch校验器逻辑错误,多余分支错误修改了password字段的校验状态,会覆盖原有必填等校验规则
  2. 同时混用了MDBootstrap原生HTML校验逻辑和Angular响应式表单校验逻辑,Angular的自定义校验错误不会同步到HTML原生validity状态,导致MDB无法识别错误展示无效样式
  3. 确认密码的错误提示没有适配自定义的mustMatch错误类型

解决方案

步骤1:修正自定义校验器逻辑

删掉校验器中给password主动设错的多余分支,仅修改确认字段的校验状态:

mustMatch(controlName: string, matchingControlName: string) {
  return (formGroup: FormGroup) => {
    const control = formGroup.controls[controlName];
    const matchingControl = formGroup.controls[matchingControlName];

    // 匹配控件本身已有其他错误时直接返回,不覆盖原有错误
    if (matchingControl.errors && !matchingControl.errors.mustMatch) {
      return;
    }

    // 仅处理值匹配逻辑
    if (control.value !== matchingControl.value) {
      matchingControl.setErrors({ mustMatch: true });
    } else {
      matchingControl.setErrors(null);
    }
  };
}

步骤2:适配模板,打通Angular校验与MDB样式

不要依赖MDB原生的needs-validation校验逻辑,改用Angular控制样式和错误提示的显示,避免两套校验逻辑冲突:

<div class="col-xs-12">
  <div class="form-outline">
    <input 
      formControlName="password" 
      type="password" 
      id="password" 
      class="form-control pb-3" 
      required
      [class.is-invalid]="signupForm.get('password')?.invalid && (signupForm.get('password')?.dirty || signupForm.get('password')?.touched || signupForm.submitted)"
    />
    <label class="form-label" for="password">密码</label>
    <div class="invalid-feedback" *ngIf="signupForm.get('password')?.errors?.['required']">
      请输入密码
    </div>
  </div>
</div>

<div class="col-xs-12">
  <div class="form-outline">
    <input 
      formControlName="confirmPassword" 
      type="password" 
      id="confirmPass" 
      class="form-control pb-3" 
      required
      [class.is-invalid]="signupForm.get('confirmPassword')?.invalid && (signupForm.get('confirmPassword')?.dirty || signupForm.get('confirmPassword')?.touched || signupForm.submitted)"
    />
    <label class="form-label" for="confirmPass">确认密码</label>
    <div class="invalid-feedback" *ngIf="signupForm.get('confirmPassword')?.errors?.['required']">
      请确认密码
    </div>
    <div class="invalid-feedback" *ngIf="signupForm.get('confirmPassword')?.errors?.['mustMatch']">
      两次输入的密码不一致
    </div>
  </div>
</div>

步骤3:清理冲突的初始化逻辑

删除ngOnInit中MDB原生表单校验的绑定逻辑,避免和Angular表单提交逻辑冲突:

ngOnInit(): void {
  document.querySelectorAll('.form-outline').forEach((formOutline) => {
    new mdb.Input(formOutline).init();
  });
  this.setupSignupForm();
  // 删除下面这段原生校验绑定代码
  // const forms = document.querySelectorAll('.needs-validation');
  // Array.prototype.slice.call(forms).forEach((form) => {
  //   form.addEventListener('submit', (event) => {
  //     if (!form.checkValidity()) {
  //       event.preventDefault();
  //       event.stopPropagation();
  //     }
  //     form.classList.add('was-validated');
  //   }, false);
  // });
}

步骤4:表单提交逻辑适配

提交表单时直接判断Angular表单的valid属性即可:

onSubmit() {
  if (this.signupForm.invalid) {
    // 标记所有字段为已触碰,触发错误提示
    Object.values(this.signupForm.controls).forEach(control => {
      control.markAsTouched();
    });
    return;
  }
  // 后续提交逻辑
}

内容的提问来源于stack exchange,提问作者web1connoisseur

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 14:36:03