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

Angular响应式表单:取消页面加载时初始验证红色高亮的方法

Angular响应式表单:仅在元素Dirty/Touched时显示验证错误提示

问题描述

开发Angular响应式表单时,页面刚加载完成,表单控件还没触发dirty或touched状态就显示了红色错误提示,需要实现仅当用户与控件交互(点击过输入框)或修改过值后,才展示验证错误样式和提示。

解决方案

核心逻辑是给错误样式和提示的显示条件加双重判断:控件本身验证不通过(invalid),同时满足dirty或touched状态;如果需要在表单提交后强制显示所有未填项错误,还可以结合表单的submitted状态。

1. 修改模板中的条件判断

针对你的代码,主要调整输入框的错误样式绑定和错误提示的显示条件:

修改后的app.html代码

<div class="container my-5">
  <div
    class="row"
    [formGroup]="profileFrm"
    #pfrm="ngForm"
    (ngSubmit)="onSubmit()"
  >
    <div class="col-6 p-3 card">
      <div class="row mb-3">
        <div class="col">
          <label for="firstName" class="form-label">First Name</label>
          <input
            type="text"
            class="form-control"
            id="firstName"
            placeholder="Enter your First Name"
            formControlName="fname"
            <!-- 调整错误样式触发条件:验证不通过 + (值被修改/控件被点击过) -->
            [class.is-invalid]="f['fname']?.invalid && (f['fname'].dirty || f['fname'].touched)"
          />
          <!-- 错误提示:仅当验证不通过且有交互时显示 -->
          <div *ngIf="f['fname']?.invalid && (f['fname'].dirty || f['fname'].touched)" class="invalid-feedback">
            First Name is required.
          </div>
        </div>
      </div>
      <hr />
      <div>
        <button
          type="submit"
          class="btn btn-sm btn-primary"
        >
          Submit
        </button>
        <button type="reset" class="btn btn-sm btn-link" (click)="onReset()">
          Clear
        </button>
      </div>
    </div>
    <div class="col-6">
      <pre>
      Output<br/>
      Submitted : {{pfrm.submitted}}
      <hr/>
      Status : {{pfrm.status}}
      </pre>
    </div>
  </div>
</div>

关键调整点

  • 输入框错误样式:把原来的touched单一判断,改成dirty || touched,覆盖用户修改值、点击过输入框两种交互场景。
  • 错误提示:原来的代码只判断了交互状态,缺少invalid校验,调整后确保只有控件确实不符合规则且有过交互时,才显示错误文本。

2. 可选:提交表单后强制显示所有错误

如果希望用户点提交按钮后,即使没碰过的必填项也显示错误,可以把表单的submitted状态加入判断:

<!-- 输入框错误样式 -->
[class.is-invalid]="(f['fname']?.invalid && (f['fname'].dirty || f['fname'].touched)) || (pfrm.submitted && f['fname']?.invalid)"

<!-- 错误提示 -->
<div *ngIf="(f['fname']?.invalid && (f['fname'].dirty || f['fname'].touched)) || (pfrm.submitted && f['fname']?.invalid)" class="invalid-feedback">
  First Name is required.
</div>

3. 组件类代码(无需修改)

你的app.ts表单初始化代码没问题,只需确保组件中定义了f属性方便模板访问控件:

import { FormBuilder, FormControl, Validators } from '@angular/forms';

// ...

this.profileFrm = this._fb.group({
  fname: new FormControl('', [Validators.required]),
});

// 新增getter,简化模板中控件的访问
get f() { return this.profileFrm.controls; }

原理说明

  • dirty:控件的值和初始值相比有过修改。
  • touched:用户已经和控件有过交互(比如点击输入框后移出焦点)。
  • 通过把invalid和dirty/touched(或submitted)结合,就能精准控制错误提示的显示时机,避免页面刚加载就出现错误样式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 08:35:38