Angular 2被动表单自定义验证器仅在表单控件有效时应用
如何实现仅在表单控件有效时应用的自定义验证器 像这样的东西很理想:Angular 2被动表单自定义验证器仅在表单控件有效时应用,angular,validation,angular-reactive-forms,Angular,Validation,Angular Reactive Forms,如何实现仅在表单控件有效时应用的自定义验证器 像这样的东西很理想: static isValid(control: FormControl) { if (control.valid) { // custom validation checks here return {isNotValid: true}; } return null; } 但是这里的control.valid始终为true,因此即使其他控件使字段无效,也会应用它 有没有办
static isValid(control: FormControl) {
if (control.valid) {
// custom validation checks here
return {isNotValid: true};
}
return null;
}
但是这里的control.valid
始终为true,因此即使其他控件使字段无效,也会应用它
有没有办法做到这一点
详细示例
源代码如下:
app.component.ts
import { Component } from '@angular/core';
import { FormControl, FormGroup } from '@angular/forms';
import { MyValidator } from './validators.service';
@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,
])
});
}
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;
}
}
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 {
// ...
}
import { MyValidator, runInOrder } from "./validators.service";
// ...
export class AppComponent {
form: FormGroup = new FormGroup({
name: new FormControl("", runInOrder([
MyValidator.isValidString,
MyValidator.isValidName
]))
});
}
如何使isValidName
验证程序仅在控件有效时应用/执行,即以前的验证程序返回null
?
因为现在,我相信angular将首先运行所有同步验证器,然后将运行所有异步验证器,并且只有在之后才会设置控制状态,我认为这是正确的方法
注意此示例仅用于演示,它没有真正的实时应用程序。尝试访问父属性,假设isValid validator用于控件,该控件是表单控件的第一级子控件,或者递归地在顶部查找父控件
static isValid(control: FormControl) {
if(control.parent) {
if(control.parent.valid) {
//custom validation
}
}
return null;
}
实现这一点的最简单方法是创建一个helper函数:
validators.service.ts
import { Component } from '@angular/core';
import { FormControl, FormGroup } from '@angular/forms';
import { MyValidator } from './validators.service';
@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,
])
});
}
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;
}
}
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 {
// ...
}
import { MyValidator, runInOrder } from "./validators.service";
// ...
export class AppComponent {
form: FormGroup = new FormGroup({
name: new FormControl("", runInOrder([
MyValidator.isValidString,
MyValidator.isValidName
]))
});
}
并将其用作自定义验证器:app.component.ts
import { Component } from '@angular/core';
import { FormControl, FormGroup } from '@angular/forms';
import { MyValidator } from './validators.service';
@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,
])
});
}
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;
}
}
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 {
// ...
}
import { MyValidator, runInOrder } from "./validators.service";
// ...
export class AppComponent {
form: FormGroup = new FormGroup({
name: new FormControl("", runInOrder([
MyValidator.isValidString,
MyValidator.isValidName
]))
});
}
这里的完整示例:为什么
控件。有效的总是有效的?编辑您的问题以添加可验证的最小示例。@HDJEMAI我已更新了问题并添加了指向活动示例的链接。希望这能澄清我的困境。你能在这里解释一下用例吗?为什么你只需要在控制有效的情况下才需要应用它?为什么现在代码本身就不能正常工作呢?首先,对于错误,我只想显示相关的错误消息。其次,为了减少无用的计算,这段代码只是一个模拟,在实际应用程序中,验证器显然更复杂,可能会对性能产生一些影响。