关于验证:如何使用MomentDateAdapter在Angular Material Datepicker上检测输入错误?

How to detect input errors on Angular Material Datepicker with MomentDateAdapter?

当前,当用户在日期选择器输入中输入无效数据时,该数据未标记为ng-invalid,而是在保存表单时将基础值设置为null。

我们的质量检查人员对此行为不满意。应该通知用户错误的输入值,并且在更正输入值之前,不能保存数据。

有没有简单的方法可以解决此问题?

日期选择器已经知道无法成功解析输入值,所以为什么不将字段标记为无效?我真的不想在自定义解析器或验证规则中重复日期解析功能。

我正在使用具有非英语语言环境和格式的moment.js适配器。
以下是我的日期选择器本地化设置,以防它们与问题相关:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
{
    provide: MAT_DATE_LOCALE, useValue: 'lv'
},
{
    provide: MAT_MOMENT_DATE_ADAPTER_OPTIONS,
    // treat all dates as UTC to avoid shifting dates to browser's timezone
    useValue: { useUtc: true }
},
{
    provide: DateAdapter,
    useClass: MomentDateAdapter,
    deps: [
        MAT_DATE_LOCALE,
        MAT_MOMENT_DATE_ADAPTER_OPTIONS
    ]
},
{
    provide: MAT_DATE_FORMATS,
    useValue: {
        parse: {
            dateInput: DEFAULT_DATE_FORMAT
        },
        display: {
            dateInput: DEFAULT_DATE_FORMAT,
            monthYearLabel: 'MMMM YYYY',
            dateA11yLabel: DEFAULT_DATE_FORMAT,
            monthYearA11yLabel: 'MMMM YYYY'
        }
    }
}

// DEFAULT_DATE_FORMAT is defined as"DD.MM.YYYY"

HTML代码:

1
2
3
4
5
6
7
8
9
10
11
<mat-form-field>
    <mat-label>My date field</mat-label>
    <input matNativeControl
           name="validTo" formControlName="validTo"
           matInput [matDatepicker]="validToPicker" placeholder="DD.MM.YYYY">
    <mat-datepicker-toggle matSuffix [for]="validToPicker"></mat-datepicker-toggle>
    <mat-datepicker touchUi #validToPicker></mat-datepicker>
    <mat-error>
        <validation-field name="validTo" [form]="form"></validation-field>
    </mat-error>
</mat-form-field>

validation-field组件是一个自定义组件,它显示字段的所有格式错误。它适用于所有其他情况,例如,对于Required验证程序,但对于错误的日期选择器输入,它不会检测到任何格式错误。输入错误的数据时,输入甚至不会标记为ng-invalid


我建议将自定义验证器添加到表单控件。如果您不使用反应形式,我会推荐(性能更高)。演示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
export class DatepickerOverviewExample {
  exampleForm: FormGroup;
  constructor(private fb: FormBuilder) {
    this.exampleForm = this.fb.group({
      date: ['', [Validators.required, CustomValidators.validateDate]]
    });
  }

}


export class CustomValidators {
  static validateDate(control: AbstractControl): object | null {
    if (!control) {
      return;
    }
    const isDateValid = true; // test date
    return isDateValid ? {
      dateInValid: true
    } : null;
  }
}
1
2
3
4
5
6
7
<mat-form-field [formGroup]="exampleForm">
  <input matInput formControlName='date' [matDatepicker]="picker" placeholder="Choose a date">
  <mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
  <mat-datepicker #picker></mat-datepicker>
</mat-form-field>

  Invalid Date!