我需要使用反应式表格angular2来检查密码和确认密码字段是否具有相同的值。我确实在这里看到了很多答案,Angular 2 form validating for repeat password,Comparing fields in validator with angular2,但似乎没有一个对我有用。可以有人请帮助。“这个”在我的验证函数中未定义:(。共享我的代码,
this.addEditUserForm = this.builder.group({
firstName: ['', Validators.required],
lastName: ['', Validators.required],
title: ['', Validators.required],
email: ['', Validators.required],
password: ['', Validators.required],
confirmPass: ['', [Validators.required, this.validatePasswordConfirmation]]
});
validatePasswordConfirmation(group: FormGroup): any{
let valid = true;
// if (this.addEditUserForm.controls.password != this.addEditUserForm.controls.confirmPass) {
// valid = false;
// this.addEditUserForm.controls.confirmPass.setErrors({validatePasswordConfirmation: true});
// }
return valid;
}
这最终对我有用 -
this.addEditUserForm = this.builder.group({
firstName: ['', Validators.required],
lastName: ['', Validators.required],
title: ['', Validators.required],
email: ['', Validators.required],
password: ['', Validators.required],
confirmPass: ['', Validators.required]
},{validator: this.checkIfMatchingPasswords('password', 'confirmPass')});
checkIfMatchingPasswords(passwordKey: string, passwordConfirmationKey: string) {
return (group: FormGroup) => {
let passwordInput = group.controls[passwordKey],
passwordConfirmationInput = group.controls[passwordConfirmationKey];
if (passwordInput.value !== passwordConfirmationInput.value) {
return passwordConfirmationInput.setErrors({notEquivalent: true})
}
else {
return passwordConfirmationInput.setErrors(null);
}
}
}
最好的方法是在表单组中有一个嵌套组,我们有一个自定义验证器,用password
和confirmPass
检查表单组,所以当其中一个字段被更改时,验证器被触发,因为之前它只在confirmPass
时触发字段已修改。
所以在外部formgroup中做这样的事情:
// ...
passwords: this.fb.group({
password: ['', [...]],
confirmPass: ['', [...]]
}, {validator: this.checkPasswords}) // add a validator for the whole group
// ...
然后验证器可能如下所示:
checkPasswords(group: FormGroup) { // here we have the 'passwords' group
let pass = group.get('password').value;
let confirmPass = group.get('confirmPass').value;
return pass === confirmPass ? null : { notSame: true }
}
然后可以像这样显示验证错误:
*ngIf="addEditUserForm.hasError('notSame', 'passwords')"
当然,您不需要拥有嵌套组,但每次表单发生任何更改时,最好不要使用自定义验证程序。这样,只有在此内部表单组发生更改时才会触发它。
如果你想这样做,你需要将函数绑定到当前的“this”上下文。通过this.validatePasswordConfirmation.bind(this)
但请注意,此函数将通过FormControl进行确认,而不是像您在函数签名中所述的FormGroup。
我做了一个不同的方法,适用于任何控制。首先,我定义表单的基本控件:
this.myForm = this.formBuilder.group({
name: ['', Validators.required],
password: ['', Validators.required],
});
然后我创建一个新控件来使用我的自定义验证器确认值:
const confirmPasswordControl = new FormControl('', {
validator: sameValueAs(this.myForm, 'password')
});
this.myForm.addControl('confirmPassword', confirmPasswordControl);
sameValueAs
验证器的代码如下,您可以在separte文件中定义它以便在任何地方使用
export function sameValueAs(group: FormGroup, controlName: string): ValidatorFn {
return (control: FormControl) => {
const myValue = control.value;
const compareValue = group.controls[controlName].value;
return (myValue === compareValue) ? null : {valueDifferentFrom:controlName};
};
}
如果您不想通过自定义验证器,您只需创建一个独立的输入字段,因此不会在formGroup中计算,而是通过ngModel计算
<input type="password" matInput [(ngModel)]="passwordConfirm" [ngModelOptions]="{standalone: true}">
然后在您的ts中,您可以根据需要验证并抛出错误或使表单无效。刚刚发现它更快更实用:
//检查密码匹配
if (this.staffAccountForm.value.password !== this.passwordConfirm) {
this.snackbar.snackBarSimple('Passwords do not match.');
return false;
}
对于那些想要添加自定义验证器而不必强制从表单组验证中传递的人,可以在定义表单后添加验证器。
此方法的一个优点是错误被添加到表单控件而不是表单组。这样就可以更容易地显示与字段关联的错误,因为我们可以直接在字段/表单控件本身上检查错误。
这是我实现它的方式:
自定义验证器
import { AbstractControl, ValidatorFn } from '@angular/forms';
export class MismatchValidator {
static mismatch(otherInputControl: AbstractControl): ValidatorFn {
return (inputControl: AbstractControl): { [key: string]: boolean } | null => {
if (inputControl.value !== undefined
&& inputControl.value.trim() != ""
&& inputControl.value !== otherInputControl.value) {
return { 'mismatch': true };
}
return null;
};
}
}
将自定义验证器应用于表单控件
ngOnInit() {
this.initForm();
// The validators are set after defining the form in order to be able to access the password control and pass it to the custom validator as a parameter
this.setValidators();
}
private initForm() {
this.myForm = this.formBuilder.group({
password: new FormControl(''),
passwordConfirmation: new FormControl('')
});
}
private setValidators() {
const formValidators = {
"password": Validators.compose([
Validators.required,
//....
]),
"passwordConfirmation": Validators.compose([
Validators.required,
MismatchValidator.mismatch(this.myForm.get("password"))
])
}
this.passwordRecoveryForm.get("password").setValidators(
formValidators["password"]
);
this.passwordRecoveryForm.get("passwordConfirmation").setValidators(
formValidators["passwordConfirmation"]
);
}
在定义表单后设置验证器,以便能够访问密码控件并将其作为参数传递给自定义验证器。