如何实现仅在表单控件有效时应用的自定义验证程序?
这样的事情是理想的:
static isValid(control: FormControl) {
if (control.valid) {
// custom validation checks here
return {isNotValid: true};
}
return null;
}
但此处control.valid
始终为true,因此即使其他会使该字段无效,也会应用它。
有没有办法实现这个目标?
此处的源代码:https://stackblitz.com/edit/angular-conditional-validator
app.component.ts
import { Component } from '@angular/core';
import { FormControl, FormGroup } from '@angular/forms';
import { MyValidator } from './my-validator';
@Component({
selector: 'my-app',
template: `
<form>
<label>Name:</label>
<input [formControl]="form.get('name')">
</form>
`
})
export class AppComponent {
form = new FormGroup ({
name: new FormControl('', [
MyValidator.isValidString,
MyValidator.isValidName,
])
});
}
my-validator.ts
import { FormControl } from '@angular/forms';
export class MyValidator {
static isValidString(control: FormControl) {
if (!control.value || typeof control.value !== 'string') {
return {isNotValidString: true};
}
return null;
}
static isValidName(control: FormControl) {
if (control.valid && control.value !== 'John Doe') {
return {isNotValidName: true};
}
return null;
}
}
如果仅在控制有效时才应用/执行isValidName
验证器,即先前的验证器返回null
?
现在,我相信angular会首先运行所有同步验证器,然后运行所有异步验证器,并且只有在设置控制状态之后,这才是我认为的正确方法。
注意
此示例仅用于演示,它没有真正的实时应用程序。
答案 0 :(得分:0)
尝试访问控制状态,如果它有效,请执行您的逻辑
if(control.status == 'VALID') {
}
答案 1 :(得分:0)
尝试访问父属性,假设isValid验证器用于控件,它是表单控件的第一级子级,或者递归查找父级到顶部
static isValid(control: FormControl) {
if(control.parent) {
if(control.parent.valid) {
//custom validation
}
}
return null;
}
答案 2 :(得分:0)
最简单的方法是创建一个辅助函数:
validators.service.ts
import { AbstractControl, FormControl, ValidationErrors, ValidatorFn } from "@angular/forms";
export function runInOrder(validators: ValidatorFn[]): ValidatorFn {
return (c: AbstractControl): ValidationErrors | null => {
for (const validator of validators) {
const resp = validator(c);
if (resp != null) {
return resp;
}
}
return null;
};
}
export class MyValidator {
// ...
}
并将其用作自定义验证器:
app.component.ts
import { MyValidator, runInOrder } from "./validators.service";
// ...
export class AppComponent {
form: FormGroup = new FormGroup({
name: new FormControl("", runInOrder([
MyValidator.isValidString,
MyValidator.isValidName
]))
});
}
完整示例在这里:
https://stackblitz.com/edit/angular-conditional-validator-solution