Angular 开始日期之前的结束日期验证在角度项目中无法正常工作

Angular 开始日期之前的结束日期验证在角度项目中无法正常工作,angular,typescript,date,validation,custom-error-handling,Angular,Typescript,Date,Validation,Custom Error Handling,我遇到了一个问题,我的结束日期验证器没有按预期执行。它确实会显示错误消息,但仅在结束日期小于启动时初始化的最小结束日期的情况下显示 例如,我的最小结束日期为当前日期+1个月(2020年2月24日),因此,只有在2020年2月24日之前选择日期时,错误才会出现在“角度材质输入”字段下。但是,我希望它仅在所选日期在当前所选开始日期之前出现,因为我已禁用日期选择器,用于最小开始日期之前的任何日期。所以正确的行为应该是:用户选择开始日期为2020年2月26日,然后抛出结束日期为2020年2月24日-->

我遇到了一个问题,我的结束日期验证器没有按预期执行。它确实会显示错误消息,但仅在结束日期小于启动时初始化的最小结束日期的情况下显示

例如,我的最小结束日期为当前日期+1个月(2020年2月24日),因此,只有在2020年2月24日之前选择日期时,错误才会出现在“角度材质输入”字段下。但是,我希望它仅在所选日期在当前所选开始日期之前出现,因为我已禁用日期选择器,用于最小开始日期之前的任何日期。所以正确的行为应该是:用户选择开始日期为2020年2月26日,然后抛出结束日期为2020年2月24日-->的错误消息

作为旁注,为了显示错误消息,我必须手动输入日期,使其早于最小结束日期

我不知所措,所以我只想包括我认为与这个问题相关的代码片段

自定义错误状态匹配器:

export class MyErrorStateMatcher implements ErrorStateMatcher {
    isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean {
      return control.parent.invalid && control.touched;
    }
}
export function EndDateAfterSelectedStartDate(group: FormGroup) {
  const startDate = group.get('startDate').value;
  console.log('startDate:', startDate);
  const endDate = group.get('endDate').value;
  console.log('endDate:', endDate);

  if (endDate < startDate) {
    console.log('Invalid End Date!');
  }

  return group.get('endDate').value < group.get('startDate').value ? { EndDateBeforeSelectedStartDate: true } : null;
}
 <div class="ui-g ui-fluid" formGroupName="date">
                <div class="ui-g-3"></div>
                <!--DATE: START AND END-->
                <mat-form-field class="ui-g-3" appearance="outline" floatLabel="auto"> 
                    <mat-label>Start Date</mat-label>
                    <input matInput formControlName="startDate" [min]="minStartDate" [max]="maxStartDate" [matDatepicker]="startPicker">
                    <mat-error>{{getErrorMessage('startDate')}}</mat-error>
                    <mat-datepicker-toggle matSuffix [for]="startPicker"></mat-datepicker-toggle>
                    <mat-datepicker touchUi="true" #startPicker></mat-datepicker>
                </mat-form-field>
                <mat-form-field class="ui-g-3" appearance="outline" floatLabel="auto"> 
                    <mat-label>End Date</mat-label>
                    <input matInput formControlName="endDate" [min]="minEndDate" [max]="maxEndDate" [matDatepicker]="endPicker">
                    <mat-error>{{getErrorMessage('endDate')}}</mat-error>
                    <mat-datepicker-toggle matSuffix [for]="endPicker"></mat-datepicker-toggle>
                    <mat-datepicker touchUi="true" #endPicker></mat-datepicker>
                </mat-form-field>
                <p>End Date: {{addPersonForm.get('room').get('date').get('endDate').value}}</p>
                <br>
                <p>Start Date: {{addPersonForm.get('room').get('date').get('startDate').value}}</p>
                <div class="ui-g-3"></div>
            </div>
this.minStartDate = new Date();
this.maxStartDate = new Date(this.minStartDate.getFullYear() + 2, this.minStartDate.getMonth(), this.minStartDate.getDate());
this.minEndDate = new Date(this.minStartDate.getFullYear(), this.minStartDate.getMonth() + 1, this.minStartDate.getDate());
this.maxEndDate = new Date(this.minEndDate.getFullYear() + 3, this.minEndDate.getMonth(), this.minEndDate.getDate());
date: this.fb.group({
  startDate: ['', [Validators.required]],
  endDate: ['', [Validators.required]],
}, {validator: this.endDateAfter}),
  case 'endDate':
    // TODO: Right now, this error is thrown when end date goes below minEndDate
    if (room.get('date').hasError('EndDateBeforeSelectedStartDate')) {
      return 'End date must be after start date';
    }
    if (room.get('date').get('endDate').hasError('required')) {
      return 'End date / move-out must be provided';
    }
    break;
自定义验证程序:

export class MyErrorStateMatcher implements ErrorStateMatcher {
    isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean {
      return control.parent.invalid && control.touched;
    }
}
export function EndDateAfterSelectedStartDate(group: FormGroup) {
  const startDate = group.get('startDate').value;
  console.log('startDate:', startDate);
  const endDate = group.get('endDate').value;
  console.log('endDate:', endDate);

  if (endDate < startDate) {
    console.log('Invalid End Date!');
  }

  return group.get('endDate').value < group.get('startDate').value ? { EndDateBeforeSelectedStartDate: true } : null;
}
 <div class="ui-g ui-fluid" formGroupName="date">
                <div class="ui-g-3"></div>
                <!--DATE: START AND END-->
                <mat-form-field class="ui-g-3" appearance="outline" floatLabel="auto"> 
                    <mat-label>Start Date</mat-label>
                    <input matInput formControlName="startDate" [min]="minStartDate" [max]="maxStartDate" [matDatepicker]="startPicker">
                    <mat-error>{{getErrorMessage('startDate')}}</mat-error>
                    <mat-datepicker-toggle matSuffix [for]="startPicker"></mat-datepicker-toggle>
                    <mat-datepicker touchUi="true" #startPicker></mat-datepicker>
                </mat-form-field>
                <mat-form-field class="ui-g-3" appearance="outline" floatLabel="auto"> 
                    <mat-label>End Date</mat-label>
                    <input matInput formControlName="endDate" [min]="minEndDate" [max]="maxEndDate" [matDatepicker]="endPicker">
                    <mat-error>{{getErrorMessage('endDate')}}</mat-error>
                    <mat-datepicker-toggle matSuffix [for]="endPicker"></mat-datepicker-toggle>
                    <mat-datepicker touchUi="true" #endPicker></mat-datepicker>
                </mat-form-field>
                <p>End Date: {{addPersonForm.get('room').get('date').get('endDate').value}}</p>
                <br>
                <p>Start Date: {{addPersonForm.get('room').get('date').get('startDate').value}}</p>
                <div class="ui-g-3"></div>
            </div>
this.minStartDate = new Date();
this.maxStartDate = new Date(this.minStartDate.getFullYear() + 2, this.minStartDate.getMonth(), this.minStartDate.getDate());
this.minEndDate = new Date(this.minStartDate.getFullYear(), this.minStartDate.getMonth() + 1, this.minStartDate.getDate());
this.maxEndDate = new Date(this.minEndDate.getFullYear() + 3, this.minEndDate.getMonth(), this.minEndDate.getDate());
date: this.fb.group({
  startDate: ['', [Validators.required]],
  endDate: ['', [Validators.required]],
}, {validator: this.endDateAfter}),
  case 'endDate':
    // TODO: Right now, this error is thrown when end date goes below minEndDate
    if (room.get('date').hasError('EndDateBeforeSelectedStartDate')) {
      return 'End date must be after start date';
    }
    if (room.get('date').get('endDate').hasError('required')) {
      return 'End date / move-out must be provided';
    }
    break;
表单组的初始化:

export class MyErrorStateMatcher implements ErrorStateMatcher {
    isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean {
      return control.parent.invalid && control.touched;
    }
}
export function EndDateAfterSelectedStartDate(group: FormGroup) {
  const startDate = group.get('startDate').value;
  console.log('startDate:', startDate);
  const endDate = group.get('endDate').value;
  console.log('endDate:', endDate);

  if (endDate < startDate) {
    console.log('Invalid End Date!');
  }

  return group.get('endDate').value < group.get('startDate').value ? { EndDateBeforeSelectedStartDate: true } : null;
}
 <div class="ui-g ui-fluid" formGroupName="date">
                <div class="ui-g-3"></div>
                <!--DATE: START AND END-->
                <mat-form-field class="ui-g-3" appearance="outline" floatLabel="auto"> 
                    <mat-label>Start Date</mat-label>
                    <input matInput formControlName="startDate" [min]="minStartDate" [max]="maxStartDate" [matDatepicker]="startPicker">
                    <mat-error>{{getErrorMessage('startDate')}}</mat-error>
                    <mat-datepicker-toggle matSuffix [for]="startPicker"></mat-datepicker-toggle>
                    <mat-datepicker touchUi="true" #startPicker></mat-datepicker>
                </mat-form-field>
                <mat-form-field class="ui-g-3" appearance="outline" floatLabel="auto"> 
                    <mat-label>End Date</mat-label>
                    <input matInput formControlName="endDate" [min]="minEndDate" [max]="maxEndDate" [matDatepicker]="endPicker">
                    <mat-error>{{getErrorMessage('endDate')}}</mat-error>
                    <mat-datepicker-toggle matSuffix [for]="endPicker"></mat-datepicker-toggle>
                    <mat-datepicker touchUi="true" #endPicker></mat-datepicker>
                </mat-form-field>
                <p>End Date: {{addPersonForm.get('room').get('date').get('endDate').value}}</p>
                <br>
                <p>Start Date: {{addPersonForm.get('room').get('date').get('startDate').value}}</p>
                <div class="ui-g-3"></div>
            </div>
this.minStartDate = new Date();
this.maxStartDate = new Date(this.minStartDate.getFullYear() + 2, this.minStartDate.getMonth(), this.minStartDate.getDate());
this.minEndDate = new Date(this.minStartDate.getFullYear(), this.minStartDate.getMonth() + 1, this.minStartDate.getDate());
this.maxEndDate = new Date(this.minEndDate.getFullYear() + 3, this.minEndDate.getMonth(), this.minEndDate.getDate());
date: this.fb.group({
  startDate: ['', [Validators.required]],
  endDate: ['', [Validators.required]],
}, {validator: this.endDateAfter}),
  case 'endDate':
    // TODO: Right now, this error is thrown when end date goes below minEndDate
    if (room.get('date').hasError('EndDateBeforeSelectedStartDate')) {
      return 'End date must be after start date';
    }
    if (room.get('date').get('endDate').hasError('required')) {
      return 'End date / move-out must be provided';
    }
    break;
GetErrorMessage():

export class MyErrorStateMatcher implements ErrorStateMatcher {
    isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean {
      return control.parent.invalid && control.touched;
    }
}
export function EndDateAfterSelectedStartDate(group: FormGroup) {
  const startDate = group.get('startDate').value;
  console.log('startDate:', startDate);
  const endDate = group.get('endDate').value;
  console.log('endDate:', endDate);

  if (endDate < startDate) {
    console.log('Invalid End Date!');
  }

  return group.get('endDate').value < group.get('startDate').value ? { EndDateBeforeSelectedStartDate: true } : null;
}
 <div class="ui-g ui-fluid" formGroupName="date">
                <div class="ui-g-3"></div>
                <!--DATE: START AND END-->
                <mat-form-field class="ui-g-3" appearance="outline" floatLabel="auto"> 
                    <mat-label>Start Date</mat-label>
                    <input matInput formControlName="startDate" [min]="minStartDate" [max]="maxStartDate" [matDatepicker]="startPicker">
                    <mat-error>{{getErrorMessage('startDate')}}</mat-error>
                    <mat-datepicker-toggle matSuffix [for]="startPicker"></mat-datepicker-toggle>
                    <mat-datepicker touchUi="true" #startPicker></mat-datepicker>
                </mat-form-field>
                <mat-form-field class="ui-g-3" appearance="outline" floatLabel="auto"> 
                    <mat-label>End Date</mat-label>
                    <input matInput formControlName="endDate" [min]="minEndDate" [max]="maxEndDate" [matDatepicker]="endPicker">
                    <mat-error>{{getErrorMessage('endDate')}}</mat-error>
                    <mat-datepicker-toggle matSuffix [for]="endPicker"></mat-datepicker-toggle>
                    <mat-datepicker touchUi="true" #endPicker></mat-datepicker>
                </mat-form-field>
                <p>End Date: {{addPersonForm.get('room').get('date').get('endDate').value}}</p>
                <br>
                <p>Start Date: {{addPersonForm.get('room').get('date').get('startDate').value}}</p>
                <div class="ui-g-3"></div>
            </div>
this.minStartDate = new Date();
this.maxStartDate = new Date(this.minStartDate.getFullYear() + 2, this.minStartDate.getMonth(), this.minStartDate.getDate());
this.minEndDate = new Date(this.minStartDate.getFullYear(), this.minStartDate.getMonth() + 1, this.minStartDate.getDate());
this.maxEndDate = new Date(this.minEndDate.getFullYear() + 3, this.minEndDate.getMonth(), this.minEndDate.getDate());
date: this.fb.group({
  startDate: ['', [Validators.required]],
  endDate: ['', [Validators.required]],
}, {validator: this.endDateAfter}),
  case 'endDate':
    // TODO: Right now, this error is thrown when end date goes below minEndDate
    if (room.get('date').hasError('EndDateBeforeSelectedStartDate')) {
      return 'End date must be after start date';
    }
    if (room.get('date').get('endDate').hasError('required')) {
      return 'End date / move-out must be provided';
    }
    break;

在表单组上设置的验证程序是
this.endDateAfter
。您尚未发布该函数的代码。您已发布EndDateAfterSelectedStartDate的代码,但该验证器似乎未被使用。抱歉,这是使用的验证器。只需更改NameEndDateAfter,它只是对实际验证器的引用