以角度反应形式使用自定义验证器

问题描述 投票:0回答:2

我正在尝试使用自定义验证器来比较结束时间是否大于开始时间。

代码:

function timeValidator(): ValidatorFn {
  return (control: AbstractControl): { [key: string]: boolean } | null => {
      if (control.value !== undefined && (isNaN(control.value) || control.get('fromTime').value > control.get('toTime').value)) {
          return { 'ageRange': true };
      }
      return null;
  };
}

来自表格组

toTime: new FormControl(null, [Validators.required, timeValidator(this.fromTime,this.toTime)]),

运行以下命令后,我收到错误:

Cannot read property 'value' of null
在线
if (control.value !== undefined && (isNaN(control.value) || control.get('fromTime').value > control.get('toTime').value))

我需要一些帮助来解决这个问题。谢谢你

angular angular7 angular-reactive-forms
2个回答
1
投票

您的自定义验证器应该放在 FormGroup 级别而不是 FormControl 级别。此外,您还应该将该函数作为参数传递,这意味着没有 () 括号,因为 timeValidator 是一个回调函数。 () 告诉 js 引擎执行该函数。但你想要的是将函数作为参数传递,这样它就可以稍后执行。

都可以

constructor(private fb: FormBuilder){}
...
this.form = this.fb.group({
    fromTime: [''],
    toTime: ['']
}, { validator: timeValidator})

 form = new FormGroup({
     toTime: new FormControl(null),
     fromTime: new FormControl(null),
 }, { validator: timeValidator})

您的自定义验证器也不应该返回函数。它应该返回一个 name:boolean 键值对。例如。 isEndGTStart: true 或 null if false

例如

export function timeValidator(fg: FormGroup){
    const fromTime = fg.get("fromTime").value;
    const toTime = fg.get("toTime).value;

    return toTime > fromTime ? { isEndGTStart: true } : null
}

0
投票
import { AbstractControl, ValidationErrors, ValidatorFn } from '@angular/forms';

export function uniqueMainChildConditionValidator(): ValidatorFn {
  return (control: AbstractControl): ValidationErrors | null => {
    if (!Array.isArray(control.value)) {
      return null; // Not an array, so we don't need to validate
    }

    const mainObjects = control.value;

    for (let i = 0; i < mainObjects.length; i++) {
      const mainObj = mainObjects[i];
      
      // Check each main object's child conditions
      if (mainObj.childCondition && mainObj.childCondition.length > 0) {
        for (const child of mainObj.childCondition) {
          if (
            mainObj.field === child.field &&
            mainObj.condition === child.condition &&
            mainObj.conditionText === child.conditionText
          ) {
            return { conditionMismatch: `Main object ${i + 1} has matching properties with a child condition.` };
          }
        }
      }

      // Check if the current main object matches any other main object
      for (let j = 0; j < mainObjects.length; j++) {
        if (i !== j) { // Ensure we are not comparing the same object
          const otherMainObj = mainObjects[j];
          if (
            mainObj.field === otherMainObj.field &&
            mainObj.condition === otherMainObj.condition &&
            mainObj.conditionText === otherMainObj.conditionText
          ) {
            return { conditionMismatch: `Main object ${i + 1} has matching properties with main object ${j + 1}.` };
          }
        }
      }
    }

    return null; // No issues found
  };
}
© www.soinside.com 2019 - 2024. All rights reserved.