自定义反应式表单验证器中的多个错误



我正在验证呼叫中心的表单,通常字段将按特定顺序填写。如果用户跳过,我想为多个字段引发错误。我发现以下工作:

export const recordValidator: ValidatorFn = (control: FormGroup): ValidationErrors | null => {
if(!firstField.value && !secondField.Value && !thirdField.value)    
{
firstField.setErrors({ "firstFieldError" : true});
secondField.setErrors({ "secondFieldError" : true});
return {"firstFieldError" : true, "secondFieldError" : true};
}
}

并且第一字段和第二字段都正确显示错误。

现在根据文档,验证错误只是错误的映射。但它显然没有任何方法,所以我想我只是将现有映射转换为 ValidationErrors 并返回:

export const recordValidator: ValidatorFn = (control: FormGroup): ValidationErrors | null => {
if(!firstField.value && !secondField.Value && !thirdField.value)    
{
firstField.setErrors({ "firstFieldError" : true});
secondField.setErrors({ "secondFieldError" : true});
let errorMap = new Map();
errorMap.set("firstFieldError",true);
errorMap.set("secondFieldError",true);
let errorValidators:ValidationErrors = errorMap;
return errorValidators;
}
}

但它不会引发任何错误。

我的模板如下所示:

<mat-form-field>
<input formControlName="firstField" type="datetime-local" placeholder="First Field" [errorStateMatcher]="errorMatcher" matInput>                        
<mat-error *ngIf="Form.errors?.firstFieldError">
First field error!
</mat-error>
</mat-form-field>

谁能帮我看看为什么第一个有效而第二个不起作用

吉姆,一个自定义验证器不能像你说的那样工作。您需要返回一个对象(或 null(。所以你的瓦利塔迪翁一定喜欢一些喜欢

export const recordValidator: ValidatorFn = (control: FormGroup): ValidationErrors | null => {
let invalid=false
const error={}
if (!control.value.firstField && control.value.secondField)
{
error.firstFieldError=true;
invalid=true;
}
if (!control.value.secondField && control.value.thirdField)
{
error.secondFieldError=true;
invalid=true;
}
return invalid?error:null;
}

看看我们如何从"控件"中获取价值 - 它是formGroup- 以及我们如何创建一个具有一个或两个属性的对象 - 如果你写信检查,你可以在你的.html中看到-

{{form.errors|json}}

注意:我真的不明白你的验证器,想象一个人在你的问题中计算描述

我需要回到这个问题,并设法在这个博客和 angular.io 的参考的帮助下正确解决它。

下面是一个返回验证错误映射的验证器:

import { Injectable } from '@angular/core';
import { AbstractControl, ValidationErrors, ValidatorFn } from '@angular/forms';
@Injectable({ providedIn: 'root' })
export class ShiftTimeValidator {
constructor() {}
//validate(time: string, shifts: VehicleShift[]): ValidatorFn {
validate(): ValidatorFn {
return (
control: AbstractControl,
): ValidationErrors => {
let errors:ValidationErrors = {};
// If the form hasn't been touched then don't validate
if (control.pristine) {
null;
}
// Check if the time falls inside any existing shifts
if(1 == 1){
errors["inside-other-shift"] = true;
}
// If the time is the start time, then check that it's before the end time
if(1 == 1){
errors["start-before-end"] = true;
}
// If the time is an end time, check that it's after the start time.
if(1 == 1){
errors["end-before-start"] = true;
}
// If the this time has an existing match, check that the new shift doesn't overlap any other shifts.
if(1 == 1){
errors["shift-overlap"] = true;
}
console.log(errors);

return errors;
};
}
}

以下是将验证器添加到表单的方法:

return this.fb.group({
vehicleShiftId: [],
vehicleId: [this.vehicle.vehicleId, Validators.required],
shiftStartTimeString: [, [Validators.required, this.shiftValidator.validate()]],
shiftEndTimeString: [, Validators.required, this.shiftValidator.validate()],
vehicleStaff: staffArray
});

以下是显示错误消息的方法:

<mat-form-field>
<input formControlName="shiftStartTimeString" type="time"
name="shiftStartTime"
placeholder="Shift start time" [errorStateMatcher]="errorMatcher" matInput>
<mat-error *ngIf="shiftStartTime?.hasError('inside-other-shift')">
Shift start time is inside another shift.
</mat-error>
<mat-error *ngIf="shiftStartTime?.hasError('start-before-end')">
Shift start time is after shift end time.
</mat-error>
<mat-error *ngIf="shiftStartTime?.hasError('end-before-start')">
Shift end time is before shift start time.
</mat-error>
<mat-error *ngIf="shiftStartTime?.hasError('shift-overlap')">
This shift overlaps another shift.
</mat-error>
</mat-form-field>

您是否应该这样做以支持为您尝试验证的每件事创建单独的验证器可能有待讨论,但这证明可以从单个验证器正确返回多个错误。

最新更新