Pas*_*cal 2 angular angular-reactive-forms angular-forms angular5
我有这些领域:
field1
field2
field3
field4
this.form = this.formbuilder.group({
'field1' = ['', [<control-specific-validations>]],
'field2' = ['', [<control-specific-validations>]]
}, { validator: isField1GreaterThanField2Validator}
});
Run Code Online (Sandbox Code Playgroud)
我需要更多验证:
- field3.value must be greater than field4.value
- field3.value must be greater than field2.value + 1
- field4.value must be less than field1.value
Run Code Online (Sandbox Code Playgroud)
您如何将这些新的验证要求集成到构建的表单中?
我确实不希望做的是建立一个
formControl.valueChanges.subscribe(value => { });
Run Code Online (Sandbox Code Playgroud)
对于每个字段,然后在那里有很多 if/else。
然后我可以删除整个反应式表单模块,使用 2way-databinding 并在验证表达式为真时在 ui 中呈现错误字符串。
vin*_*nce 11
您可以使用自定义验证器来执行此操作。https://angular.io/guide/form-validation#custom-validators
这是您想要的工作示例:https : //stackblitz.com/edit/isgreaterthanotherfield-custom-validator
验证器函数本身如下所示:
greaterThan(field: string): ValidatorFn {
return (control: AbstractControl): {[key: string]: any} => {
const group = control.parent;
const fieldToCompare = group.get(field);
const isLessThan = Number(fieldToCompare.value) > Number(control.value);
return isLessThan ? {'lessThan': {value: control.value}} : null;
}
}
Run Code Online (Sandbox Code Playgroud)
我正在使用parent控件上的属性来访问其他字段。
请注意,您不能在表单初始化中设置该验证器,因为您所基于的字段尚未定义。
this.myForm = this.fb.group({
field1: 0,
field2: 0
});
this.myForm.get('field2').setValidators(this.greaterThan('field1'));
Run Code Online (Sandbox Code Playgroud)
更新:我更进一步,实现了一个接受谓词函数的自定义验证器,因此您可以使用相同的验证器进行所有比较。
在这里查看它的实际效果:https : //stackblitz.com/edit/comparison-custom-validator
它使用与上面相同的方法,但更灵活一点,因为您可以传入任何比较。该示例没有考虑一些边缘情况,例如传递不存在的表单字段名称,如果您传递的表单字段实际上没有使用数字/类型不匹配等,但我相信超出了问题的范围。
这是一个有趣的问题,我喜欢研究它。
为了快速参考,以下是使用灵活的自定义验证器的整个组件的外观:
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
myForm: FormGroup;
field2HasError: boolean;
field3HasError: boolean;
constructor(private fb: FormBuilder) {}
ngOnInit() {
this.myForm = this.fb.group({
field1: 0,
field2: 0,
field3: 0,
field4: 0
});
const field1MustBeGreaterThanField2 =
this.comparison('field1', (field2Val, field1Val) => {
return Number(field2Val) < Number(field1Val);
});
const field3MustBeGreaterThanField2Plus1 =
this.comparison('field2', (field3Val, field2Val) => {
return Number(field3Val) > (Number(field2Val) + 1);
});
this.myForm.get('field2').setValidators(field1MustBeGreaterThanField2);
this.myForm.get('field3').setValidators(field3MustBeGreaterThanField2Plus1);
this.myForm.get('field2').valueChanges.subscribe(() => {
this.field2HasError = this.myForm.get('field2').hasError('comparison');
});
this.myForm.get('field3').valueChanges.subscribe(() => {
this.field3HasError = this.myForm.get('field3').hasError('comparison');
});
}
comparison(field: string, predicate: (fieldVal, fieldToCompareVal) => boolean): ValidatorFn {
return (control: AbstractControl): {[key: string]: any} => {
const group = control.parent;
const fieldToCompare = group.get(field);
console.log('fieldToCompare.value', fieldToCompare.value);
console.log('field.value', control.value);
const valid = predicate(control.value, fieldToCompare.value);
return valid ? null : {'comparison': {value: control.value}};
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
8544 次 |
| 最近记录: |