Angular 4 - 具有动态参数值的自定义验证器

时间:2017-10-20 12:56:36

标签: javascript angular validation typescript

我编写了一个自定义验证程序,用于检查日期是否超过某个最小日期。

代码如下所示:

export function validateMinDate(min: Date): ValidatorFn {
    return (c: AbstractControl) => {

        if (c == null || c.value == null)
            return null;

        let isValid = c.value >= min;
        if (isValid) {
            return null;
        } else {
            return {
                validateMinDate: {
                    valid: false
                }
            };
        }
    };
}

我像这样启动我的表单

    this.definitionForm = this.fb.group({            
        "from": [this.details.From, Validators.required],
        "to": [this.details.To, [Validators.required, validateMinDate(this.details.From)]]
    });

我可以看到验证器正在应用,但当我console.log()验证器中的最小值时,我可以看到它等于null

当我启动表单时,

this.details.From从null开始,所以我假设参数不是动态的,只是在设置表单时获取值?

当用户从日期中选择一个时,如何确保更新最小日期,从而更改this.details.From的值?

3 个答案:

答案 0 :(得分:3)

@Nicolas Validator仅在不查找更改时才取值。因此,我们可以通过在值更改时分配新的验证器来动态更改参数值。在您的情况下,您可以采用以下方式:

 onChanges(){
   var self=this;
    this.definitionForm.get('from').valueChanges.subscribe(val => {
     this.from=val;
     this.definitionForm.controls['to'].
     setValidators(Validators.compose([Validators.required, 
     TimeValidators.isTimeAfter(this.from)]));
})}

在这里,我创建了一个单独的自定义验证器来比较时间。您可以使用它或修改您的

import { FormControl, Validators,ValidatorFn, AbstractControl} from '@angular/forms';

export class TimeValidators extends Validators{

  static isTimeBefore(timeStr : string): ValidatorFn{
    return(c: AbstractControl): {[key:string]: boolean} | null => {
      if(c.value!==undefined && (isNaN(c.value)) || c.value > timeStr || c.value== timeStr){
        return {
          'isTimeBefore':true
        }
      }
      return null;
    }
  }
  static isTimeAfter(timeStr : string): ValidatorFn{
    return(c: AbstractControl): {[key:string]: boolean} | null => {
      if(c.value!==undefined && (isNaN(c.value)) && (c.value < timeStr || c.value == timeStr)){
        return {
          'isTimeAfter':true
        }
      }
      return null;
    }
  }
}

初始化onChanges()后,调用definitionForm FormGroup函数。

答案 1 :(得分:2)

我如何看待它,是在表单组上应用验证器,或者如果你有一个大表单,我建议你为tothis.definitionForm = this.fb.group({ "from": [this.details.From, Validators.required], "to": [this.details.To, [Validators.required]] }, {validator: validateMinDate()}); export function validateMinDate(): ValidatorFn { return (c: AbstractControl) => { if(c) { let isValid = c.get('to').value >= c.get('from').value; if (isValid) { return null; } else { return {validateMinDate: true}; } } }; } 创建一个嵌套组并应用验证器在那,因为否则只要表格发生任何变化,就会触发这个自定义验证器。因此,将验证器和表单组更新为:

setErrors

当然还有其他选项,例如侦听更改事件,然后检查日期,如果无效,请在表单上使用android.support.v7.widget.SearchView

答案 2 :(得分:1)

您可以修改自定义验证器以将函数作为参数,如

export function validateMinDate(min: DateFunc): ValidatorFn {
return (c: AbstractControl) => {

    if (c == null || c.value == null)
        return null;

    let isValid = c.value >= min();
    if (isValid) {
        return null;
    } else {
        return {
            validateMinDate: {
                valid: false
            }
        };
    }
};

并像这样启动表单

 this.definitionForm = this.fb.group({            
    ...
    "to": [this.details.To, [Validators.required, validateMinDate(() => this.details.From)]]
});

DateFunc 只是一种您可以创建的类型

export interface DateFunc{
 (): Date
}

并期望 this.details.From 返回 Date 类型的值