Angular 未显示反应式 md 错误的自定义验证器
Angular custom validator for reactive form md-error not showing
如果密码不匹配,我无法显示我的 *ngIf
。
<md-form-field>
<input mdInput placeholder="Repeat password" type="password" formControlName="repeat">
<md-error *ngIf="form.controls['repeat'].errors?.required">Field required</md-error>
<md-error *ngIf="form.errors?.matchingPasswords">passwords don't match</md-error>
</md-form-field>
这是我的构造函数
constructor(private formBuilder: FormBuilder) {
this.form = this.formBuilder.group({
username:
['',
Validators.compose([
Validators.required,
Validators.minLength(3),
Validators.maxLength(30),
this.validateUsername,
this.validateUsernameAvailability
])
],
email:
['',
Validators.compose([
Validators.required,
Validators.maxLength(30),
this.validateEmail
])
],
password:
['',
Validators.compose([
Validators.required,
Validators.minLength(8),
Validators.maxLength(30),
this.validatePassword
])
],
repeat: ['',
Validators.compose([
Validators.required
])
]
}, {validator: this.matchingPasswords('password', 'repeat')});
}
matchingPasswords(password, repeat) {
return (group: FormGroup) => {
// Check if both fields are the same
if (group.controls[password].value === group.controls[repeat].value) {
return null; // Return as a match
} else {
return { 'matchingPasswords': true }; // Return as error: do not match
}
};
}
@编辑
使用简单的 <span>
而不是 <md-error>
似乎可以解决问题。
<span *ngIf="form.errors?.matchingPasswords">passwords don't match</span>
但是为什么 <md-error>
没有出现?
似乎是“bug',需要解决方法。
md-error
inside md-form-field
只验证特定输入,不考虑任何其他输入。因此,如果您将 移到 之外 md-form-field
它将生效,但当然 css 在这种情况下会被弄乱。解决方法是改用 md-hint
并用 css 修改它以模拟 md-error
:
<md-hint *ngIf="form.errors?.matchingPasswords">passwords don't match</md-hint>
只是把它丢在那里你可以跳过自定义验证器并像这样使用 Custom Error Matcher:
myErrorStateMatcher(control: FormControl): boolean {
if(control.parent.controls.password.value === control.value) {
control.setErrors(null)
return false;
}
else {
control.setErrors({notSame:true})
return true;
}
}
在模板中:
<input mdInput formControlName="repeat" [errorStateMatcher]="myErrorStateMatcher">
但是有了这个,你真的无法控制它何时被触发。尽管使用您目前拥有的代码,只要 any 发生变化,您的自定义验证器也会被触发。然后,检查下面的 旁注。
旁注:
如果使用 md-hint
,我会将 password
和 repeat
包装在一个嵌套表单组中,并将自定义验证器应用于该嵌套表单组,以便仅触发它当这两个表单控件中的任何一个发生更改时。
至于 repeat
表单控件,除了检查它是否与 password
字段匹配之外,我认为没有必要使用任何其他验证。
如果密码不匹配,我无法显示我的 *ngIf
。
<md-form-field>
<input mdInput placeholder="Repeat password" type="password" formControlName="repeat">
<md-error *ngIf="form.controls['repeat'].errors?.required">Field required</md-error>
<md-error *ngIf="form.errors?.matchingPasswords">passwords don't match</md-error>
</md-form-field>
这是我的构造函数
constructor(private formBuilder: FormBuilder) {
this.form = this.formBuilder.group({
username:
['',
Validators.compose([
Validators.required,
Validators.minLength(3),
Validators.maxLength(30),
this.validateUsername,
this.validateUsernameAvailability
])
],
email:
['',
Validators.compose([
Validators.required,
Validators.maxLength(30),
this.validateEmail
])
],
password:
['',
Validators.compose([
Validators.required,
Validators.minLength(8),
Validators.maxLength(30),
this.validatePassword
])
],
repeat: ['',
Validators.compose([
Validators.required
])
]
}, {validator: this.matchingPasswords('password', 'repeat')});
}
matchingPasswords(password, repeat) {
return (group: FormGroup) => {
// Check if both fields are the same
if (group.controls[password].value === group.controls[repeat].value) {
return null; // Return as a match
} else {
return { 'matchingPasswords': true }; // Return as error: do not match
}
};
}
@编辑
使用简单的 <span>
而不是 <md-error>
似乎可以解决问题。
<span *ngIf="form.errors?.matchingPasswords">passwords don't match</span>
但是为什么 <md-error>
没有出现?
似乎是“bug',需要解决方法。
md-error
inside md-form-field
只验证特定输入,不考虑任何其他输入。因此,如果您将 移到 之外 md-form-field
它将生效,但当然 css 在这种情况下会被弄乱。解决方法是改用 md-hint
并用 css 修改它以模拟 md-error
:
<md-hint *ngIf="form.errors?.matchingPasswords">passwords don't match</md-hint>
只是把它丢在那里你可以跳过自定义验证器并像这样使用 Custom Error Matcher:
myErrorStateMatcher(control: FormControl): boolean {
if(control.parent.controls.password.value === control.value) {
control.setErrors(null)
return false;
}
else {
control.setErrors({notSame:true})
return true;
}
}
在模板中:
<input mdInput formControlName="repeat" [errorStateMatcher]="myErrorStateMatcher">
但是有了这个,你真的无法控制它何时被触发。尽管使用您目前拥有的代码,只要 any 发生变化,您的自定义验证器也会被触发。然后,检查下面的 旁注。
旁注:
如果使用 md-hint
,我会将 password
和 repeat
包装在一个嵌套表单组中,并将自定义验证器应用于该嵌套表单组,以便仅触发它当这两个表单控件中的任何一个发生更改时。
至于 repeat
表单控件,除了检查它是否与 password
字段匹配之外,我认为没有必要使用任何其他验证。