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}
 });
我需要更多验证:
- 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
您如何将这些新的验证要求集成到构建的表单中?
我确实不希望做的是建立一个
formControl.valueChanges.subscribe(value => { });
对于每个字段,然后在那里有很多 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;
  }
}
我正在使用parent控件上的属性来访问其他字段。
请注意,您不能在表单初始化中设置该验证器,因为您所基于的字段尚未定义。
this.myForm = this.fb.group({
  field1: 0,
  field2: 0
});
this.myForm.get('field2').setValidators(this.greaterThan('field1'));
更新:我更进一步,实现了一个接受谓词函数的自定义验证器,因此您可以使用相同的验证器进行所有比较。
在这里查看它的实际效果: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}};
    }
  }
}
| 归档时间: | 
 | 
| 查看次数: | 8544 次 | 
| 最近记录: |