gpt4 book ai didi

angular - 当不同的字段更改值时如何重新触发验证器

转载 作者:行者123 更新时间:2023-12-04 07:20:50 27 4
gpt4 key购买 nike

我编写了一个简单的自定义验证器来比较两个密码字段,如果它们不匹配则发出错误信号。这里是:

@Directive({
selector: '[appMatchPassword]',
providers: [
{ provide: NG_VALIDATORS, useExisting: MatchPasswordDirective, multi: true }
]
})
export class MatchPasswordDirective implements Validator {

@Input('appMatchPassword') otherControl: string = '';

constructor() { }

registerOnValidatorChange(fn: () => void): void {
}

validate(control: AbstractControl): ValidationErrors | null {

const compareTo = control.parent?.get(this.otherControl);
if (!compareTo) return null;

if (compareTo?.value !== control.value) return {
appMatchPassword: true
}

return null;
}

}
模板像这样引用它:
    <mat-form-field>
<mat-label>Password</mat-label>
<input matInput type="password" name="password" [(ngModel)]="user.password"
required minlength="4" #iPassword="ngModel">
<mat-error *ngIf="iPassword.errors?.required">Password Required.</mat-error>
<mat-error *ngIf="iPassword.errors?.minlength">Minimum 4 characters</mat-error>
</mat-form-field>

<mat-form-field>
<mat-label>Verify Password</mat-label>
<input matInput type="password" name="vpassword" [(ngModel)]="vpassword"
required appMatchPassword="password" #fvp="ngModel">
<mat-error *ngIf="fvp.errors?.appMatchPassword">Passwords do not match</mat-error>
</mat-form-field>
如果用户在 password 中输入一个值,这将按预期工作。字段和 vpassword 中的不同值 field 。如果用户更正 vpassword 中的值,该错误将显示并消失。 field 。
但是,如果用户返回并编辑 password字段错误不会消失。验证器仅在其自己的 AbstractControl 更改值后才被调用。
password时,有什么好的方法可以触发Validator字段被改变?

最佳答案

您必须使用 cross-field validation并将您的验证器指令应用于表单本身,而不是密码字段。
如果验证器发出错误,它将出现在表单的错误数组中,而不是特定字段的错误数组中。
此外,如果您想显示 mat-errormat-form-field它不会显示,因为该字段本身不是无效的(仅整个表单)-因此您可以移动 mat-error在外面,或使用 custom error state matcher
简而言之,这是您的指令的外观(请注意,现在传递给 validate 方法的控件是整个表单,而不是特定字段)

validate(control: AbstractControl): ValidationErrors | null {
const pass = control.get('password')?.value;
const vpass = control.get('vpassword')?.value;

console.log(pass,vpass);

if (pass !== vpass)
return {
appMatchPassword: true
};

return null;
}
这是您的模板的外观:
<!-- the directive is applied to the form -->
<form #frm="ngForm" appMatchPassword>
<mat-form-field>
<mat-label>Password</mat-label>
<input matInput type="password" name="password" [(ngModel)]="user.password"
required minlength="4" #iPassword="ngModel">
<mat-error *ngIf="iPassword.errors?.required">Password Required.</mat-error>
<mat-error *ngIf="iPassword.errors?.minlength">Minimum 4 characters</mat-error>
</mat-form-field>

<mat-form-field>
<mat-label>Verify Password</mat-label>

<!-- the directive is NOT applied to the particular field -->
<!-- also note the `matcher` property, see below... -->
<input matInput type="password" name="vpassword" [(ngModel)]="vpassword" required
[errorStateMatcher]="matcher">

<!-- this line changed, it now looks at frm.errors instead of fvp.errors -->
<mat-error *ngIf="frm.errors?.appMatchPassword">Passwords do not match</mat-error>
</mat-form-field>
</form>
这是一个虚拟错误状态匹配器,它总是显示任何 mat-error现有领域:
export class AlwaysShowErrors implements ErrorStateMatcher {
isErrorState(control: FormControl, form: FormGroupDirective | NgForm): boolean {
return true;
}
}
将其实例化为 matcher组件类中的字段因此:
matcher = new AlwaysShowErrors();
StackBlitz例子

关于angular - 当不同的字段更改值时如何重新触发验证器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68513699/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com