Angular5响应式表单添加自定义验证器及密码验证器绑定问题
我来帮你搞定Angular 5响应式表单里的自定义验证器问题,还有你遇到的密码验证器绑定失效的坑~
在Angular 5响应式表单中添加自定义验证器
自定义验证器本质上就是一个接收FormControl参数,返回{[key: string]: boolean} | null的函数。你已经用静态类方法的方式封装验证器,这个思路是对的,咱们先把密码验证器的代码补全并修正:
1. 完善密码验证器的实现
import { FormControl } from "@angular/forms"; export class PasswordValidator { // 静态方法返回验证函数 static getPasswordValidator() { return function passwordValidator(control: FormControl): { [s: string]: boolean } | null { // 密码规则:至少6位,包含大小写字母和数字 const validPassword = /^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9]).{6,}$/; // 当控件有值但不匹配规则时,返回错误对象 if (control.value && !validPassword.test(control.value)) { // 这里的键(invalidPassword)是后续在HTML中判断错误的标识 return { invalidPassword: true }; } // 验证通过必须返回null,否则Angular会判定验证失败 return null; }; } }
2. 在响应式表单中应用自定义验证器
接下来在组件的表单组里,把这个验证器绑定到密码控件上,和内置验证器(比如Validators.required)一起使用:
import { Component } from '@angular/core'; import { FormBuilder, FormGroup, Validators } from '@angular/forms'; import { PasswordValidator } from './password.validator'; // 导入验证器类 @Component({ selector: 'app-login', templateUrl: './login.component.html' }) export class LoginComponent { loginForm: FormGroup; constructor(private fb: FormBuilder) { this.initLoginForm(); } private initLoginForm() { this.loginForm = this.fb.group({ username: ['', Validators.required], password: [ '', [ Validators.required, // 内置必填验证 PasswordValidator.getPasswordValidator() // 应用自定义密码验证 ] ] }); } }
解决密码验证器在HTML中的绑定问题
你之前用loginForm.controls.password.errors.passwordValidator无效,核心原因是:错误对象的键是你在验证函数里返回的那个键(比如上面的invalidPassword),而不是验证函数的名字。咱们修正HTML模板的错误判断逻辑:
<form [formGroup]="loginForm" (ngSubmit)="onSubmit()"> <!-- 用户名输入框 --> <div class="form-group"> <label>用户名</label> <input type="text" formControlName="username" class="form-control"> <div *ngIf="loginForm.get('username').invalid && loginForm.get('username').touched" class="text-danger"> <span>用户名不能为空</span> </div> </div> <!-- 密码输入框 --> <div class="form-group"> <label>密码</label> <input type="password" formControlName="password" class="form-control"> <div *ngIf="loginForm.get('password').invalid && loginForm.get('password').touched" class="text-danger"> <span *ngIf="loginForm.get('password').errors.required">密码不能为空</span> <!-- 这里用咱们定义的invalidPassword键来判断错误 --> <span *ngIf="loginForm.get('password').errors.invalidPassword"> 密码必须至少6位,且包含大小写字母和数字 </span> </div> </div> <button type="submit" class="btn btn-primary" [disabled]="loginForm.invalid">登录</button> </form>
额外小提示
- 可以用
loginForm.get('password')替代loginForm.controls.password,写法更简洁灵活; - 一定要在验证通过时返回
null,不然哪怕输入符合规则,Angular也会认为验证失败; - 建议加上
touched判断,避免用户还没输入就显示错误提示,提升体验。
内容的提问来源于stack exchange,提问作者CodeHip
相关产品推荐
相关产品推荐

