我正在实施更改密码屏幕我需要检查密码和确认密码的相等性。所以我正在实施自定义验证。
但我得到一些例外" matcher.isErrorState不是一个函数"。请在下面找到我的代码,让我知道我身边缺少的东西。
TypeScript文件 -
export class ChangePasswordComponent implements OnInit {
password :any;
confirmPassword:any;
form :any ;
constructor(fb: FormBuilder, private authService: AuthService, private router: Router) {
this.password = new FormControl('', [Validators.required,Validators.minLength(8) , Validators.maxLength(20), Validators.pattern(new RegExp("(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])"))]);
this.confirmPassword = new FormControl('', [Validators.required, Validators.minLength(8) , Validators.maxLength(20)]);
this.form = fb.group({
password :this.password ,
confirmPassword :this.confirmPassword
});
var that = this;
this.form.controls.confirmPassword.setValidators([this.cross(this.password)]);
}
cross( p) {
console.log("in cross");
console.log(p);
return null;
}
}
Html组件文件 -
<form [formGroup]="form" class="example-form" >
<mat-form-field style="width: 100%">
<input matInput placeholder="Enter your password" [type]="'password'" formControlName="password" required>
<mat-error *ngIf="form.controls.password.invalid">{{validatePassword()}}</mat-error>
</mat-form-field>
<br>
<br>
<mat-form-field style="width: 100%">
<input matInput placeholder="Confirm your password" [type]="'password'" formControlName="confirmPassword" required>
<mat-error *ngIf="form.controls.confirmPassword.invalid">{{validateConfirmPassword()}}</mat-error>
</mat-form-field>
<br>
<button color="primary" (click)="changePassword()" [disabled]="!(form.controls.confirmPassword.valid || form.controls.password.valid)" mat-raised-button>Submit</button>
</form>
答案 0 :(得分:1)
查看这篇文章,我认为将为您提供一个很好的理解{i 3}}
基本上你需要做的是分配给de confirm密码控制这样的自定义验证器:
FAIL["test_should_update_preference", Minitest::Result, 1.8134876039985102]
test_should_update_preference#Minitest::Result (1.82s)
Expected response to be a redirect to <http://www.example.com/preferences> but was a redirect to <http://www.example.com/institutes>.
Expected "http://www.example.com/preferences" to be === "http://www.example.com/institutes".
test/controllers/preferences_controller_test.rb:20:in `block in <class:PreferencesControllerTest>'
然后你可以通过传递密码formControl
来使用这个验证器export const confirmValidator = (password: FormControl) =>
(confirmPassword: FormControl): ValidationErrors | null => {
// return a object with error type if there is some kind of error
// return null if there is no error
}
试试这个让我知道
答案 1 :(得分:0)
创建自定义指令equal-validator.directive.ts
import { Directive, forwardRef, Attribute } from '@angular/core';
import { Validator, AbstractControl, NG_VALIDATORS } from '@angular/forms';
@Directive({
selector: '[validateEqual][formControlName],[validateEqual][formControl],[validateEqual][ngModel]',
providers: [
{ provide: NG_VALIDATORS, useExisting: forwardRef(() => EqualValidatorDirective), multi: true }
]
})
export class EqualValidatorDirective {
constructor( @Attribute('validateEqual') public validateEqual: string) {}
validate(c: AbstractControl): { [key: string]: any } {
// self value (e.g. retype password)
let v = c.value;
// control value (e.g. password)
let e = c.root.get(this.validateEqual);
// value not equal
if (e && v !== e.value) return {
validateEqual: false
}
return null;
}
}
Html(在确认密码字段中使用validateEqual =“password”)
<form class="login-form" (ngSubmit)="onSubmit(f)" #f="ngForm">
<div class="col-lg-12 header">
Member Register
</div>
<div class="form-group">
<div class="col-lg-12">
<mat-form-field class="example-full-width">
<input type="password" matInput placeholder="Password" name="password" [(ngModel)]="user.password" #password="ngModel" required
minlength="8" maxlength="20" pattern="((?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%]).{8,20})">
</mat-form-field>
</div>
<div class="col-lg-12">
<mat-error *ngIf="password.touched">
<mat-error *ngIf="password.errors?.required">
Password is
<strong>required</strong>
</mat-error>
<mat-error *ngIf="password.errors?.pattern">
Password is
<strong>Invalid</strong>
</mat-error>
</mat-error>
</div>
</div>
<div class="form-group">
<div class="col-lg-12">
<mat-form-field class="example-full-width">
<input type="password" matInput placeholder="Confirm Password" name="confirmPassword" [(ngModel)]="user.confirmPassword"
#confirmPassword="ngModel" required validateEqual="password">
</mat-form-field>
</div>
<div class="col-lg-12">
<mat-error *ngIf="confirmPassword.touched">
<mat-error *ngIf="confirmPassword.errors?.required">
Confirm Password is
<strong>required</strong>
</mat-error>
<mat-error *ngIf="!(confirmPassword.valid || confirmPassword.pristine)">
Password amd Confirm Password is
<strong>Not matched</strong>
</mat-error>
</mat-error>
</div>
</div>
<div class="form-group">
<div class="col-lg-12">
<button mat-button [disabled]="f.invalid">Register</button>
</div>
<div class="col-lg-12">
<div class="center">
<mat-error>
{{messageText}}
</mat-error>
</div>
</div>
</div>
</form>
答案 2 :(得分:0)
实际上,您正在验证表单中的两个字段如何相互交互(“密码”和“确认密码”字段)。这称为“ 跨领域验证”
这意味着您的自定义验证器不能仅分配给1个字段。需要将自定义验证器分配给公共父窗体,即表单。
这是官方记录的最佳实践,用于验证表单中的2个字段如何相互影响
https://angular.io/guide/form-validation#cross-field-validation
此代码段对我有用
模板:
<form method="post" [formGroup]="newPasswordForm">
<input type="password" formControlName="newPassword" />
<input type="password" formControlName="newPasswordConfirm" />
<div class="err-msg" *ngIf="newPasswordForm.errors?.passwordMismatch && (newPasswordForm.touched || newPasswordForm.dirty)">
confirm-password does not match password
</div>
</form>
component.ts:
export class Component implements OnInit {
this.newPasswordForm = new FormGroup({
'newPassword': new FormControl('', [
Validators.required,
]),
'newPasswordConfirm': new FormControl('', [
Validators.required
])
}, { validators: passwordMatchValidator });
}
export const passwordMatchValidator: ValidatorFn = (formGroup: FormGroup): ValidationErrors | null => {
return formGroup.get('newPassword').value === formGroup.get('newPasswordConfirm').value ?
null : { 'passwordMismatch': true };
}
请注意,对于passwordMatchValidator
,它在组件类之外。它不在课程之内