Angular (4): Custom Validator in a Template-Driven form 显示后面字段的当前值
Angular (4): Custom Validator in a Template-Driven form shows the current value of the field behind
我似乎无法弄清楚为什么我的自定义验证器比字段值落后一步。示例:我的输入字段的值是 123,一一输入。但是我的验证器的值为 12。
我无法正确比较两个字段之间的值。
这是指令中的验证器:
@Directive({
selector: '[validateEqual][formControlName],[validateEqual][formControl],[validateEqual][ngModel]',
providers: [
{
provide: NG_VALIDATORS,
useExisting: forwardRef(() => PasswordValidationDirective),
multi: true
}
]
})
export class PasswordValidationDirective implements Validator {
@Input('first') first: string;
@Input('second') second: string;
constructor() {
}
public validate(ac: AbstractControl): { [key: string]: any } {
console.log(ac.root);
return null;
}
}
这是字段的html:
<md-input-container class="full-width">
<input mdInput
type="password"
required
ngModel name="passwordConfirmation"
#passwordConfirmation="ngModel"
minlength="6"
maxlength="30"
pattern="(?=^.{6,30}$)((?=.*\d)|(?=.*\W+))(?![.\n])(?=.*[A-Z])(?=.*[a-z]).*$"
validateEqual
first="password"
second="passwordConfirmation"
placeholder="{{'PASSWORD_RECOVERY.PASSWORD_CONFIRMATION' | translate}}">
<md-error *ngIf="passwordConfirmation.touched && passwordConfirmation.invalid">
<span *ngIf="passwordConfirmation.errors.required">
{{'PASSWORD_RECOVERY.FIELD_REQUIRED' | translate}}
</span>
<span *ngIf="passwordConfirmation.errors.minlength || passwordConfirmation.errors.maxlength">
{{'PASSWORD_RECOVERY.PASSWORD_LENGTH' | translate}}
</span>
<span *ngIf="passwordConfirmation.errors.pattern" class="p-md-error-multiline-div">
{{'PASSWORD_RECOVERY.FOR_A_SECURE_PASSWORD' | translate}}
</span>
</md-error>
</md-input-container>
终于找到解决办法了!我决定选择 NgModelGroup
。这是指令:
@Directive({
selector: '[validateEqual][ngModelGroup]',
providers: [
{
provide: NG_VALIDATORS,
useExisting: forwardRef(() => PasswordValidationDirective),
multi: true
}
]
})
export class PasswordValidationDirective implements Validator {
@Input('password') public password: string;
@Input('confirmation') public confirmation: string;
public validate(fg: FormGroup): { [key: string]: any } {
const fieldOne = fg.value[this.password];
const fieldTwo = fg.value[this.confirmation];
if (!fieldOne || !fieldTwo || fieldOne === fieldTwo ) {
return null;
}
return {valueEquals: false};
}
}
这里是 HTML:
<div ngModelGroup="passwordGroup"
#passwordGroup="ngModelGroup"
validateEqual
password="password"
confirmation="passwordConfirmation">
<div class="row">
<div class="col-xs-6">
<md-input-container class="full-width">
<input mdInput
type="password"
required
ngModel name="password"
#password="ngModel"
placeholder="{{'SIGNUP.PASSWORD' | translate}}">
</md-input-container>
</div>
<div class="col-xs-6">
<md-input-container class="full-width">
<input mdInput
type="password"
required
ngModel name="passwordConfirmation"
#passwordConfirmation="ngModel"
placeholder="{{'SIGNUP.RETYPE_PASSWORD' | translate}}">
</md-input-container>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<md-error *ngIf="passwordGroup.errors">
<span class="p-text-small-error">{{'SIGNUP.MATCH' | translate}}</span>
</md-error>
</div>
</div>
</div>
这里重要的部分是指令本身和传入的参数,可以根据自己的喜好进行修改。
我似乎无法弄清楚为什么我的自定义验证器比字段值落后一步。示例:我的输入字段的值是 123,一一输入。但是我的验证器的值为 12。
我无法正确比较两个字段之间的值。 这是指令中的验证器:
@Directive({
selector: '[validateEqual][formControlName],[validateEqual][formControl],[validateEqual][ngModel]',
providers: [
{
provide: NG_VALIDATORS,
useExisting: forwardRef(() => PasswordValidationDirective),
multi: true
}
]
})
export class PasswordValidationDirective implements Validator {
@Input('first') first: string;
@Input('second') second: string;
constructor() {
}
public validate(ac: AbstractControl): { [key: string]: any } {
console.log(ac.root);
return null;
}
}
这是字段的html:
<md-input-container class="full-width">
<input mdInput
type="password"
required
ngModel name="passwordConfirmation"
#passwordConfirmation="ngModel"
minlength="6"
maxlength="30"
pattern="(?=^.{6,30}$)((?=.*\d)|(?=.*\W+))(?![.\n])(?=.*[A-Z])(?=.*[a-z]).*$"
validateEqual
first="password"
second="passwordConfirmation"
placeholder="{{'PASSWORD_RECOVERY.PASSWORD_CONFIRMATION' | translate}}">
<md-error *ngIf="passwordConfirmation.touched && passwordConfirmation.invalid">
<span *ngIf="passwordConfirmation.errors.required">
{{'PASSWORD_RECOVERY.FIELD_REQUIRED' | translate}}
</span>
<span *ngIf="passwordConfirmation.errors.minlength || passwordConfirmation.errors.maxlength">
{{'PASSWORD_RECOVERY.PASSWORD_LENGTH' | translate}}
</span>
<span *ngIf="passwordConfirmation.errors.pattern" class="p-md-error-multiline-div">
{{'PASSWORD_RECOVERY.FOR_A_SECURE_PASSWORD' | translate}}
</span>
</md-error>
</md-input-container>
终于找到解决办法了!我决定选择 NgModelGroup
。这是指令:
@Directive({
selector: '[validateEqual][ngModelGroup]',
providers: [
{
provide: NG_VALIDATORS,
useExisting: forwardRef(() => PasswordValidationDirective),
multi: true
}
]
})
export class PasswordValidationDirective implements Validator {
@Input('password') public password: string;
@Input('confirmation') public confirmation: string;
public validate(fg: FormGroup): { [key: string]: any } {
const fieldOne = fg.value[this.password];
const fieldTwo = fg.value[this.confirmation];
if (!fieldOne || !fieldTwo || fieldOne === fieldTwo ) {
return null;
}
return {valueEquals: false};
}
}
这里是 HTML:
<div ngModelGroup="passwordGroup"
#passwordGroup="ngModelGroup"
validateEqual
password="password"
confirmation="passwordConfirmation">
<div class="row">
<div class="col-xs-6">
<md-input-container class="full-width">
<input mdInput
type="password"
required
ngModel name="password"
#password="ngModel"
placeholder="{{'SIGNUP.PASSWORD' | translate}}">
</md-input-container>
</div>
<div class="col-xs-6">
<md-input-container class="full-width">
<input mdInput
type="password"
required
ngModel name="passwordConfirmation"
#passwordConfirmation="ngModel"
placeholder="{{'SIGNUP.RETYPE_PASSWORD' | translate}}">
</md-input-container>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<md-error *ngIf="passwordGroup.errors">
<span class="p-text-small-error">{{'SIGNUP.MATCH' | translate}}</span>
</md-error>
</div>
</div>
</div>
这里重要的部分是指令本身和传入的参数,可以根据自己的喜好进行修改。