提问人:AntoBoy 提问时间:10/30/2023 最后编辑:AntoBoy 更新时间:10/30/2023 访问量:68
Angular 验证器被忽略或不工作
Angular validators are ignored or not working
问:
我使用ReactiveForms。我有一个登录组件,我使用两个输入字段(电子邮件和密码)。此输入字段都来自同一个自定义组件“TextFieldComponent”。我尝试在我的电子邮件输入上添加一个特定的正则表达式验证器,在我的密码输入上添加一个 minLength 验证器(仅用于测试)。当我输入有效的电子邮件地址时,我收到自定义错误消息“无效的电子邮件地址”,但事实并非如此。此外,对于密码输入,不考虑 minLength 验证器。
LoginComponent TS中:
import { Component, OnInit } from '@angular/core';
import { AuthService } from '../../auth.service';
import { FormControl, FormGroup, Validators } from '@angular/forms';
import { LoginRequest } from 'src/app/shared/models/login-request';
import { Router } from '@angular/router';
import { HttpErrorResponse } from '@angular/common/http';
@Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.scss']
})
export class LoginComponent implements OnInit {
loginForm: FormGroup;
ngOnInit(): void {
this.createLoginForm();
}
createLoginForm(): void {
this.loginForm = new FormGroup({
email: new FormControl(null, [Validators.required, Validators.pattern(/^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/)]),
password: new FormControl(null, [Validators.required, Validators.minLength(4)])
});
}
}
LoginComponent 模板
<form (ngSubmit)="onSubmit()" [formGroup]="loginForm" class="form-signin">
<h1 class="h3 mb-3 font-weight-normal text-center">Please sign in</h1>
<app-text-input
[formControlName]="'email'"
[label]="'Email address'">
</app-text-input>
<app-text-input
[formControlName]="'password'"
[label]="'Password'"
[type]="'password'">
</app-text-input>
<app-button [disabled]="loginForm.invalid" type="submit" label="Sign in" className="btn btn-primary w-100" class="w-100"></app-button>
</form>
TextFieldComponent TS
import { Component, ElementRef, Input, Self, ViewChild } from '@angular/core';
import { AbstractControl, NgControl } from '@angular/forms';
@Component({
selector: 'app-text-input',
templateUrl: './text-input.component.html',
styleUrls: ['./text-input.component.scss']
})
export class TextInputComponent {
@ViewChild('input', {static : true}) input: ElementRef; // reference to the input field
@Input() type : 'email' | 'text' | 'password' = 'text'; // input type (password, text, date, button, ...)
@Input() label: string; // Label that describes the input field
constructor(
@Self() public controlDir: NgControl
) {
// Bind the valueAccessor to this particular class, which lets us access the control directive inside our component + template
this.controlDir.valueAccessor = this;
}
ngOnInit(): void {
const control = this.controlDir.control as AbstractControl;
control.updateValueAndValidity();
}
onChange(event? : any) { }
onTouched(event? : any) {}
writeValue(obj: any): void {
this.input.nativeElement.value = obj || '';
}
registerOnChange(fn: any): void {
this.onChange = fn;
}
registerOnTouched(fn: any): void {
this.onTouched = fn;
}
}
TextFieldComponent 模板
<div class="form-label-group">
<label for="{{label}}">{{label}}</label>
<input #input [ngClass]="(controlDir && controlDir.control && controlDir.control.touched)
? !controlDir.control.valid
? 'is-invalid'
: 'is-valid'
: null" [type]="type" (input)="onChange($event)" (blur)="onTouched()" id="{{label}}"
class="form-control" placeholder="{{label}}" autocomplete="off" >
<!-- Synchornous Error Messages -->
<!-- Invalid control check -->
<div *ngIf="(
controlDir &&
controlDir.control &&
!controlDir.control.valid &&
controlDir.control.touched
)" class="invalid-feedback">
<!-- Required control check -->
<span *ngIf="controlDir.control.errors?.['required']">{{label}} is required</span>
<!-- Pattern control check -->
<div *ngIf="controlDir.control.errors?.['pattern']">Invalid Email Format</div>
</div>
有人知道我的验证器出了什么问题以及为什么它们没有按预期工作吗?
答:
1赞
Eliseo
10/30/2023
#1
问题出在自定义窗体控件上。
你有:
<input #input ... (input)="OnChange($event)">
$event是输入事件,则应使用
<input #input ... (input)="onChange(input.value)">
或创建函数
change(event:any)
{
this.onChange(event.target.value)
}
//and use
<input #input ... (input)="change($event)">
提示:有时,要检查FormGroup是util write in .html(在本例中为loginComponent)
<pre>
{{loginForm.value|json}}
</pre>
注意:通常是一个自定义窗体控件,用于制作“复杂 UI”。您可以创建带有标签、错误...使用 viewProvider,例如 this SO
评论
0赞
AntoBoy
10/30/2023
多谢。我确实遵循了上面的解决方案:它有效。也感谢您的提示。标记为已接受<input #input ... (input)="onChange(input.value)">
评论
^[\w\-\.]+@([\w-]+\.)+[\w]{2,4}$
^[\w\-\.]+@([\w-]+\.)+[\w-]{2,4}$
-
Validators.pattern(/...../)
^
$