Angular FormBuilder group弃用:自定义验证器报错求助
Angular自定义验证器报错修复方案
问题1:FormBuilder.group配置属性名错误
你在创建FormGroup时,配置对象里写的是Validators: this.validatorService.camposIguales('password','password2'),但Angular的AbstractControlOptions要求属性名是小写的validators。大写的Validators会被当成普通自定义属性,导致Angular识别不到你要设置的表单级验证器,进而触发"API类型不安全"的报错。
问题2:单个控件验证器的参数类型不符合要求
你的noPuedesSerYo验证器参数类型是FormControl,但报错提示明确要求验证器参数必须是AbstractControl类型(不能用子类),因为Angular调用验证器时传入的是AbstractControl实例,无法自动向下转换为子类,这会导致类型安全问题和Closure Compiler重命名问题。
修改后的代码
1. ValidatorService修改
import { Injectable } from '@angular/core'; import { AbstractControl, ValidationErrors } from '@angular/forms'; @Injectable({ providedIn: 'root' }) export class ValidatorService { public nombreApellidoPattern:string = '([a-zA-Z]+) (.+[a-zA-Z])'; public emailPattern: string = "^[a-z0-9._%+-]+@[a-z0-9.-]+\\.[a-z]{2,4}$"; constructor() { } // 将参数类型从FormControl改为AbstractControl noPuedesSerYo (control: AbstractControl): ValidationErrors | null { const valor:string = control.value?.trim().toLowerCase(); if(valor === 'pepepepon'){ return {noYo:true}; } return null; } camposIguales(campo1:string, campo2:string){ return (control: AbstractControl)=>{ const pass1 = control.get(campo1)?.value; const pass2 = control.get(campo2)?.value; if(pass1 !== pass2){ return {noIguales:true}; } // 建议不要手动设置子控件errors,避免覆盖其他验证错误 // control.get(campo2)?.setErrors(null); return null; } } }
2. 组件代码修改
import { Component, OnInit } from '@angular/core'; import {FormBuilder, FormGroup, Validators } from '@angular/forms'; import { ValidatorService } from 'src/app/shared/validator/validator.service'; @Component({ selector: 'app-registro', templateUrl: './registro.component.html', styleUrls: ['./registro.component.css'] }) export class RegistroComponent implements OnInit { miFormulario:FormGroup = this.fb.group({ nombre:['',[Validators.required, Validators.pattern(this.validatorService.nombreApellidoPattern)]], email:['',[Validators.required, Validators.pattern(this.validatorService.emailPattern)]], username:['',[Validators.required, this.validatorService.noPuedesSerYo]], password:['',[Validators.required,Validators.minLength(6)]], password2:['',[Validators.required]] },{ // 把Validators改成小写的validators validators: this.validatorService.camposIguales('password','password2') }); constructor(private fb:FormBuilder, private validatorService:ValidatorService){} ngOnInit(): void { this.miFormulario.reset({ nombre:'', email:'', username:'', password:'', password2:'' }) } campoInvalido(campo:string){ return this.miFormulario.get(campo)?.invalid && this.miFormulario.get(campo)?.touched; } submitForm(){ this.miFormulario.markAllAsTouched(); } }
额外优化建议
在camposIguales验证器里,不要手动调用control.get(campo2)?.setErrors(null),因为这会清除password2控件的其他验证错误(比如required)。表单级验证器只需要返回对应的错误对象即可,Angular会自动管理控件的错误状态。
内容的提问来源于stack exchange,提问作者pepepepon
相关产品推荐
相关产品推荐

