我正在使用Angular 5 Reactive forms
,并设置form group
说confirmEmail
,其中两个form controls
为email
和confirmEmail
。我进一步向validator
添加了form group
,并form controls
附加了required
次验证。
My use case is
:我想根据各个表单控件的值触发custom validation
,如果自定义验证程序返回为invalid
,请将表单控件标记为有错误。< / p>
My issue is that
:form controls
标记有错误后,自定义验证程序(在表单组上)不再触发,直到我再次触摸两个表单控件并更改它们的值。
理想情况下,我希望只更新其中一个字段(以匹配另一个字段)并能够再次触发自定义验证。
示例代码:
@Component({...})
export class FormComponent implements OnInit {
user: FormGroup;
constructor(private fb: FormBuilder) {}
ngOnInit() {
this.user = this.fb.group({
data: this.fb.group({
email: ['', Validators.required],
confirmEmail: ['', Validators.required]
}, , { validator: validateEmail })
});
}
const validateEmail = (control: AbstractControl): {[key: string]: boolean} => {
const email = control.get('email');
const confirmEmail = control.get('confirmEmail');
if (email.value === confirmEmail.value) {
return null;
} else {
this.setFieldAsInvalid(email);
this.setFieldAsInvalid(confirmEmail);
return { nomatch: true };
}
};
private setFieldAsInvalid(field: AbstractControl) {
field.setErrors({
'invalid': true
});
}
}
有任何建议可以解决这个或我应采取的任何其他方法。
答案 0 :(得分:0)
当控件(email和confirmEmail)保持不同的值时,你将它们更改为无效,但 return null
在ValidatorFun中只会将当前的formcontrol的有效值更改为true,并非所有电子邮件和确认电子邮件。
<强>解决方法1:强>
您可以更改电子邮件,并在保持相同值时通过field.setErrors(null)
确认电子邮件返回有效。
if (email.value === confirmEmail.value) {
// clear custom error for all related controls
this.setFieldAsValid(email);
this.setFieldAsValid(confirmEmail);
return null;
} else {
this.setFieldAsInvalid(email);
this.setFieldAsInvalid(confirmEmail);
return { nomatch: true };
}
private setFieldAsValid(field: AbstractControl) {
field.setErrors(null);
}
查看已修复的 demo 。
<强>溶液2:强>
如果您只关心错误nomatch
,则可以跟踪表单组data
,看看它是否有nomatch
错误,如下所示(也包含在上面的演示模板中部分):
this.user.get('data').hasError('nomatch')
提到这种方式会使另一个formcontrol无效。
答案 1 :(得分:0)
我使用反应式方法创建了一个示例表单,其中我使用了内置验证器和自定义验证器。
打字稿:
export class AppComponent {
forbiddenEmails = ['test@test.com'];
loginForm = new FormGroup({
'name': new FormControl(null, [Validators.required]),
'email': new FormControl(null, [Validators.required, Validators.email, this.customEmailValidator.bind(this)])
});
onSubmit(){
console.log(this.loginForm.get('email').value);
}
customEmailValidator(control: FormControl): {[params: string]: boolean}{
console.log(this.forbiddenEmails.indexOf(control.value));
if(this.forbiddenEmails.indexOf(control.value) === 0){
return {'forbiddenEmail': true};
}else{
return null;
}
}
}
模板:
<h3>Basic Form</h3>
<form class="form-horizontal" [formGroup]='loginForm' (ngSubmit)="onSubmit()">
<div class="form-group">
<label for="name" class="col-sm-3 control-label">Name:</label>
<div class="col-sm-6">
<input type="text"
id="name"
class="form-control"
formControlName='name' />
</div>
<div class="col-sm-3"></div>
<span *ngIf='loginForm.get("name").invalid && loginForm.get("name").touched'>Pleas enter a valid name !!!</span>
</div>
<div class="form-group">
<label for="email" class="col-sm-3 control-label">Email:</label>
<div class="col-sm-6">
<input type="email"
id="email"
class="form-control"
formControlName="email"/>
</div>
<div class="col-sm-3"></div>
<span *ngIf='loginForm.get("email").invalid && loginForm.get("email").touched'>Pleas enter a valid email !!!</span>
</div>
<hr>
<button class="btn btn-primary"
type="submit"
[disabled]='!loginForm.valid'
>Submit</button>
</form>
链接:https://stackblitz.com/edit/angular-nwahpa?file=app%2Fapp.component.html