Angular2表单自定义验证指令

时间:2017-06-15 16:22:30

标签: angular validation directive

我尝试使用Angular 2实现反应式表单,我在自定义验证器方面遇到了一些问题。

如果输入字段的值在输入字段的(minDate)和(maxDate)属性之间,我尝试使日期字段有效。如果未提供先前的值之一,则对最小和最大约束没有限制。

问题是当" start_date "字段已修改。 " start_date "触发了字段验证器(行为正常),但验证者是" end_date "尽管(maxDate)属性更改,但不会触发字段。我可以看到,因为" ngOnChanges "指令的方法被调用。

你知道我哪里错了吗?

非常感谢你的帮助。

这是我的代码:

组件:

this.task = this.formBuilder.group({
  name: ['', Validators.required],
  start_date: ['', Validators.required],
  end_date: ['', Validators.required]
});

Vue的:

<form [formGroup]="task" (ngSubmit)="onSubmit()" novalidate>

<label for="name"><b>Name</b>: </label>
  <input id="name" name="name" formControlName="name"/><br>

<label for="start_date"><b>Start</b>: </label>
  <input id="start_date" name="start_date" formControlName="start_date" 
   [maxDate]="task.get('end_date').value"
   appDateValidator/><br>

<label for="end_date"><b>End</b>: </label>
  <input id="end_date" name="end_date" formControlName="end_date"
  [minDate]="task.get('start_date').value"
   appDateValidator/><br>

</form>

指令/校验器:

@Directive({
 selector: '[appDateValidator]',
 providers: [{ provide: NG_VALIDATORS, useExisting: DateValidatorDirective, multi: true }]
})
export class DateValidatorDirective implements Validator, OnChanges {

  @Input() minDate: string;
  @Input() maxDate: string;
  private valFn = Validators.nullValidator;

  constructor() { }

  ngOnChanges(changes: SimpleChanges): void {
    const minDateChange = changes['minDate'];
    const maxDateChange = changes['maxDate'];
    if (minDateChange) {
      this.minDate = minDateChange.currentValue;
    }
    if (maxDateChange) {
      this.maxDate = maxDateChange.currentValue;
    }
    this.valFn = DateValidator(this.minDate, this.maxDate);
  }

  validate(c: AbstractControl): ValidationErrors {
    return this.valFn(c);
  }
}

export function DateValidator(minDate: string, maxDate: string): ValidatorFn {
  return (c: AbstractControl): { [key: string]: any } => {
  let errors = null;

  const dateValueMoment = moment.utc(c.value, moment.ISO_8601);
  const minDateMoment = minDate ? moment.utc(minDate, moment.ISO_8601) : moment.invalid();
  const maxDateMoment = maxDate ? moment.utc(maxDate, moment.ISO_8601) : moment.invalid();
  if (!dateValueMoment.isValid()) {
    errors = Object.assign({}, errors, {
      'value': c.value
    });
  }
  if (minDateMoment.isValid() && dateValueMoment.isBefore(minDate)) {
    errors = Object.assign({}, errors, {
      'min': minDate
    });
  }
  if (maxDateMoment.isValid() && dateValueMoment.isAfter(maxDate)) {
    errors = Object.assign({}, errors, {
      'max': maxDate
    });
  }

  return errors;
  };
}

0 个答案:

没有答案