反应验证Angular 5:编写自定义验证器以比较两个控件

时间:2018-04-11 19:30:03

标签: angular validation angular-reactive-forms

我希望只有在验证失败时才会禁用我的保存按钮... 验证1:startTime<时间结束 验证2:两者都为空或两者都有数据(已经在24小时 - 小时:毫米)。 我的实施 - 1.。文件:

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文件
  2. <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&lt; endTime,现在将endTime减小到startTime,然后再次使startTime小于EndTime .---&gt;保存将被禁用但它的错误应该处于能够状态。

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

2 个答案:

答案 0 :(得分:0)

您可以通过其他方式实现相同的目标,即使用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;
    }


  }

答案 1 :(得分:0)

在您的说明中,您提到验证应为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