如何正确使用Angular表单校验?实现字段校验与错误视觉反馈
组件代码(component.ts)修改
- 为表单控件添加 getter 时使用非空断言
!,明确告知 TypeScript 该控件必然存在,解决"object is possibly null"报错 - 提交函数新增前置校验,表单无效时直接阻止提交并触发所有控件的错误状态
import { Component, OnInit } from '@angular/core'; import { FormGroup, FormControl, Validators } from '@angular/forms'; import { AuthService } from 'src/app/services/auth.service'; import { Router } from '@angular/router'; @Component({ selector: 'app-register', templateUrl: './register.component.html', styleUrls: ['./register.component.scss'] }) export class RegisterComponent implements OnInit { // 加非空断言,确认ngOnInit一定会初始化该表单 form!: FormGroup; error: string = ''; constructor(private auth: AuthService, private router: Router) { } // 新增表单控件getter get name() { return this.form.get('name')!; } get email() { return this.form.get('email')!; } get password() { return this.form.get('password')!; } ngOnInit(): void { this.form = new FormGroup({ name: new FormControl('', [Validators.required]), email: new FormControl('', [ Validators.required, Validators.pattern("^[a-z0-9._%+-]+@[a-z0-9.-]+\\.[a-z]{2,4}$") ]), password: new FormControl('', [ Validators.required, Validators.minLength(8) ]) }) } submit(){ // 新增前置校验 if (this.form.invalid) { // 标记所有控件为已触碰,触发错误样式 this.form.markAllAsTouched(); return; } this.auth.tryRegister(this.form.getRawValue()) .subscribe( res => { if(res.status == 200){ this.router.navigate(['/verify']) }}, err => { if(err.status == 400){ this.error = 'Invalid form data' } else if(err.status == 401){ this.error = 'email address already in use' } }) } }
模板代码修改
- 给form标签添加模板引用变量
#regForm="ngForm"获取表单提交状态 - 给每个input绑定动态类,满足「非法+已修改/已触碰/表单已提交」条件时,添加自定义的
is-invalid类 - 可选添加对应错误提示文本
<div class="content"> <section> <div class="form-wrapper"> <h3>Registrieren</h3> <form class="form" [formGroup]="form" (submit)="submit()" #regForm="ngForm"> <div class="form-item"> <input type="text" formControlName="name" placeholder="Name" [ngClass]="{'is-invalid': name.invalid && (name.dirty || name.touched || regForm.submitted)}" > <!-- 可选错误提示 --> <span *ngIf="name.invalid && (name.dirty || name.touched || regForm.submitted)" class="error-text"> 请输入姓名 </span> </div> <div class="form-item"> <input formControlName="email" type="email" placeholder="Email Addresse" [ngClass]="{'is-invalid': email.invalid && (email.dirty || email.touched || regForm.submitted)}" > <!-- 分类型错误提示 --> <span *ngIf="email.errors?.['required'] && (email.dirty || email.touched || regForm.submitted)" class="error-text"> 请输入邮箱 </span> <span *ngIf="email.errors?.['pattern'] && (email.dirty || email.touched || regForm.submitted)" class="error-text"> 请输入合法的邮箱地址 </span> </div> <div class="form-item"> <input formControlName="password" type="password" placeholder="Passwort" [ngClass]="{'is-invalid': password.invalid && (password.dirty || password.touched || regForm.submitted)}" > <span *ngIf="password.errors?.['required'] && (password.dirty || password.touched || regForm.submitted)" class="error-text"> 请输入密码 </span> <span *ngIf="password.errors?.['minlength'] && (password.dirty || password.touched || regForm.submitted)" class="error-text"> 密码长度不能少于8位 </span> </div> <div class="form-item"> <button type="submit">Registrieren</button> </div> </form> </div> </section> </div>
样式补充
在组件的scss文件中添加对应样式即可:
.is-invalid { border: 1px solid #f5222d; } .error-text { color: #f5222d; font-size: 12px; margin-top: 4px; display: block; }
如果你不想使用自定义类,也可以直接对Angular内置的状态类写样式,Angular会自动给非法的已修改/已触碰控件添加ng-invalid、ng-dirty、ng-touched类,直接对这些类设置样式即可实现相同效果。
内容的提问来源于stack exchange,提问作者Kleecarim
相关产品推荐
相关产品推荐

