反应式验证 Angular 5:编写用于比较两个控件的自定义验证器

Reactive Validation Angular 5: Writing Custom validator for comparing two controls

我希望仅在验证失败时禁用我的保存按钮... 验证 1:开始时间 < 结束时间 Validation2 :两者都为空或都有数据(已经在 24hr-hh:mm 中)。 我的实施- 1..ts文件:

private createForm() {
    this.commentForm = new FormGroup({
     'startTime': new 
      FormControl(this.startTime, 
      [
       this.openCloseTimeValidator
      ]),
     'endTime': new 
      FormControl(this.endTime, [
      this.openCloseTimeValidator
    ]),});
  }

openCloseTimeValidator(control: FormControl) {
    const commentFormGroup = control.root;
    const startTime = ((commentFormGroup.get('startTime')) ? 
    commentFormGroup.get('startTime').value : null);
    const endTime = ((commentFormGroup.get('endTime')) ? 
    commentFormGroup.get('endTime').value : null);
    return startTime && endTime && (startTime >= endTime) ?
               { 'openCloseTimeValidator' : true } : null;
 }
  1. .html 文件

<form  [formGroup]="commentForm">
  <div formGroupName="noiseOrdinance">
  <div fxFlex class= "time-picker">
    <time-picker  placeholder="Start Time"
      formControlName="startTime"  type="text"></time-picker>
  </div>
  <div fxFlex class= "time-picker">
  <time-picker  placeholder="End Time" formControlName="endTime" 
    type="text"></time-picker>
  </div>
  </div>
  <button mat-button [disabled]="!commentForm.valid">Save</button>
</form>

此验证工作不正常,请考虑以下情况:最初 startTime< endTime,现在将 endTime 减小到小于 startTime,然后再次使 startTime 小于 EndTime。---> 保存将被禁用,但它的错了应该是有能力的状态。

如果选中和取消选中包含在复选框中的 html-snippet,验证值会更新。但 在控制台日志上:我得到 ExpressionChangedAfterItHasBeenCheckedError

您可以通过其他方式实现相同的目的,即使用 ngmodel 和 ngModelChange:

举个例子:

在你的 HTML、

在两个<time-picker>标签中连续添加这两个

[(ngModel)]="searchTimeIni" (ngModelChange)=checkValid() 
[(ngModel)]="searchTimeFin" (ngModelChange)=checkValid()

按钮标记为

<button mat-button [disabled]="!valid">Save</button>

TS文件中

valid: boolean = false;



checkValid() {


    if (this.searchTimeIni=== undefined && this.searchTimeFin=== undefined) {
      this.valid = false;

    }
    else if (this.searchTimeIni< this.searchTimeFin) { 


      this.valid = true;
    }
    else if (this.searchTimeIni> this.searchTimeFin) { 


      this.valid = false;
    }


  }

在您的描述中,您提到验证应该是 startTime < endTime,但您在验证器中键入的是 startTime && endTime && (startTime >= endTime)

无论如何,您的验证器可能如下所示:

import { Component } from '@angular/core';
import { FormControl, ValidatorFn, FormGroup, FormBuilder } from '@angular/forms';

const timeValidator: ValidatorFn = (ctrl: FormGroup) => {
  const start = ctrl.get('startTime').value;
  const end = ctrl.get('endTime').value;

  return start && end && start < end ? null : { 'timeError': true };
}

@Component({
  selector: 'my-app',
  template: `
   <form [formGroup]="form">
    <input type="number" formControlName="startTime" />
    <input type="number" formControlName="endTime" />
  </form>

  Valid: {{ form.valid }}
  `,
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  form: FormGroup;

  // pretend it's epoch time
  startTime = 1000;
  endTime = 2000;

  constructor(private fb: FormBuilder) {
    this.form = this.fb.group({
      startTime: [this.startTime],
      endTime: [this.endTime],
    }, { validator: timeValidator })
  }
}

Live demo