我在 Reactive Forms 中開發了一個表單,用戶可以在其中設定新密碼。他輸入舊密碼和新密碼并確認新密碼。我考慮過以下情況:
- 新密碼不能包含舊密碼
- 新密碼和確認密碼匹配
開發也有效。現在我有一件不好的事情。僅當我更改輸入欄位中的某些內容時才會觸發驗證。但是現在想確認密碼的時候又想修改新密碼,這樣就知道有沒有錯誤了。我已經讀到這可以通過函式 updateValueAndValidity 來完成。你知道怎么做嗎?
我的代碼:
// TS
changePasswordForm: FormGroup;
submitted = false;
ngOnInit() {
// To initialize forms
this.initChangePasswordForm();
}
// Creation of the changePasswordForm
private initChangePasswordForm() {
// General
this.changePasswordForm = this.formBuilder.group({
old_password: [null, Validators.pattern('^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[^\\w\\s]).{8,}$')],
new_password: [null, this.customComparePasswordValidator],
confirm_password: [null, Validators.required]
});
}
customComparePasswordValidator(control: FormControl) {
const newPassword = control.value;
if (newPassword && newPassword.length) {
const oldPassword = control.parent.value.old_password;
if (oldPassword && oldPassword.length && newPassword.toLowerCase().includes(oldPassword.toLowerCase())) {
return { newPasswordIncludesOldPassword: true };
}
const pattern = new RegExp('^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[^\\w\\s]).{8,}$');
if (!pattern.test(newPassword)) {
return { newPasswordInvalid: true };
}
} else {
return { required: true };
}
}
// HTML
<input matInput type="password" placeholder="aktuelles Passwort" formControlName="old_password" required>
<p *ngIf="changePasswordForm.get('old_password').invalid && (changePasswordForm.get('old_password').dirty || changePasswordForm.get('old_password').touched)">
<mat-error class="custom-validation-error" *ngIf="changePasswordForm.get('old_password').hasError('required')">aktuelles Passwort eingeben</mat-error>
<mat-error class="custom-validation-error" *ngIf="changePasswordForm.get('old_password').hasError('pattern')">8 oder mehr Zeichen mit einer Mischung aus Gro?- und Kleinbuchstaben, Ziffern und Symbolen verwenden</mat-error>
</p>
<input matInput type="password" placeholder="neues Passwort" formControlName="new_password" required>
<p *ngIf="changePasswordForm.get('new_password').invalid && (changePasswordForm.get('new_password').dirty || changePasswordForm.get('new_password').touched)">
<mat-error *ngIf="changePasswordForm.get('new_password').hasError('required')">neues Passwort eingeben</mat-error>
<mat-error *ngIf="changePasswordForm.get('new_password').hasError('newPasswordInvalid')">8 oder mehr Zeichen mit einer Mischung aus Gro?- und Kleinbuchstaben, Ziffern und Symbolen verwenden</mat-error>
<mat-error *ngIf="changePasswordForm.get('new_password').hasError('newPasswordIncludesOldPassword')">Neues und altes Passwort dürfen nicht gleich sein</mat-error>
</p>
<input matInput type="password" placeholder="Passwort best?tigen" formControlName="confirm_password" appConfirmEqualValidator="new_password" required>
<p *ngIf="changePasswordForm.get('confirm_password').invalid && (changePasswordForm.get('confirm_password').dirty || changePasswordForm.get('confirm_password').touched)">
<mat-error *ngIf="changePasswordForm.get('confirm_password').hasError('required')">Passwort erneut eingeben</mat-error>
<mat-error *ngIf="changePasswordForm.get('confirm_password').hasError('notEqual') && !changePasswordForm.get('confirm_password').hasError('required')">Passwort stimmt nicht überein</mat-error>
</p>
我的 StackBlitz:https ://stackblitz.com/edit/example-angular-material-reactive-form-sr1keu ? file = app/app.component.html
uj5u.com熱心網友回復:
正如您所說,驗證器僅在您更改 FormControl 時“檢查”。因此,您可以在更改第二個控制元件時“強制”使一個控制元件有效。因此,例如,您只需在 FormControl 中的“new_password”中寫入即可
<input matInput ... formControlName="new_password"
(input)="changePasswordForm.get('confirm_password').updateValueAndValidity()" />
(與其他 FormControl 相同)
您還可以在創建表單后訂閱 valueChanges - 不要忘記取消訂閱 -
private initChangePasswordForm() {
// After create the formGroup
this.changePasswordForm = this.formBuilder.group({..}
//subscribe to changes "new_password"
this.changePasswordForm.get('new_password').valueChanges
.subscribe(_=>{
this.changePasswordForm.get('confirm_password').updateValueAndValidity()
})
另一種方法是在整個表單上創建一個 customValidator。當您使用材料時,您需要使用 setErrors。驗證器可以像
validatorRepeatPassword(form: FormGroup) {
const errorOldPassword = {};
const errorNewPassword = {};
const errorConfirmPassword = {};
const pattern = new RegExp(
'^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[^\\w\\s]).{8,}$'
);
if (!form.value.old_password) errorOldPassword['required'] = true;
else {
if (!pattern.test(form.value.old_password))
errorOldPassword['pattern'] =
'8 or more characters with a mixture of upper and lower case letters,use numbers and symbols';
}
if (!form.value.new_password) errorNewPassword['required'] = true;
else {
if (!pattern.test(form.value.new_password))
errorNewPassword['pattern'] =
'8 or more characters with a mixture of upper and lower case letters,use numbers and symbols';
if (
form.value.old_password &&
form.value.new_password
.toLowerCase()
.includes(form.value.old_password.toLowerCase())
)
errorNewPassword['newPasswordIncludesOldPassword'] = true;
}
if (!form.value.confirm_password) errorConfirmPassword['required'] = true;
else {
if (
form.value.new_password &&
form.value.confirm_password != form.value.new_password
)
errorConfirmPassword['notEqual'] = true;
}
form.controls.old_password.setErrors(
Object.keys(errorOldPassword).length ? errorOldPassword : null
);
form.controls.new_password.setErrors(
Object.keys(errorNewPassword).length ? errorNewPassword : null
);
form.controls.confirm_password.setErrors(
Object.keys(errorConfirmPassword).length ? errorConfirmPassword : null
);
return {
...errorOldPassword,
...errorNewPassword,
...errorConfirmPassword,
};
}
并使用
this.changePasswordForm = this.formBuilder.group(
{
old_password: null,
new_password: null,
confirm_password: null,
},
{ validator: this.validatorRepeatPassword }
);
最后一種方法(我只用 new_password 和確認密碼創建驗證器是用兩個控制元件創建的。一個函式像
matchValidator(field: string,not:boolean=false) {
return (control: AbstractControl) => {
const parent = control.parent;
const controlCompare = parent ? parent.get(field) : null;
if (controlCompare && controlCompare.value && control.value) {
const invalid = controlCompare.value != control.value;
if (invalid!=controlCompare.invalid)
{
setTimeout(()=>{
controlCompare.updateValueAndValidity();
})
}
return invalid && !not ? { match: 'no match' } : null;
}
};
}
允許我們寫,例如
this.changePasswordForm = this.formBuilder.group(
{
old_password: null,
new_password: [null,this.matchValidator('confirm_password',true)],
confirm_password: [null,this.matchValidator('confirm_password',true)]
}
);
看到你使用一個函式來傳遞引數 - 這應該是固定的 -
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/320977.html
