具有多个同步验证器的角形式有效,尽管它应该无效

时间:2018-02-08 22:06:56

标签: angular angular5 angular-forms

我有2个FormControls。

当其中一个控件值大于/小于另一个控件的值时,我得到了正确的错误验证,该错误验证写在我的html中,而form.valid为TRUE。

this.bestGradeScoresFormControl.setValidators(bestScoresGreaterThanWorstScoresValidator(this.worstGradeScoresFormControl), 
Validators.max(100)]);
this.worstGradeScoresFormControl.setValidators(worstScoresSmallerThanBestScoresValidator(this.bestGradeScoresFormControl));

然后我使用Compose函数将Validators.max(100)添加到bestScores控件:

this.bestGradeScoresFormControl.setValidators(Validators.compose(
[bestScoresGreaterThanWorstScoresValidator(this.worstGradeScoresFormControl), Validators.max(100)]));
this.worstGradeScoresFormControl.setValidators(worstScoresSmallerThanBestScoresValidator(this.bestGradeScoresFormControl));

当我为最佳分数控制设置101分时,我得到:'不允许超过100分数' form.valid为FALSE,即CORRECT!

但是...

当我现在将最差得分控制值更改为有效值时,然后将之前的最大错误值'突然disappers和form.valid为TRUE,这是不正确的!

我没有使用Compose方法,而是尝试使用一系列验证器,如:

this.bestGradeScoresFormControl.setValidators([bestScoresGreaterThanWorstScoresValidator(this.worstGradeScoresFormControl), Validators.max(100)]);
  this.worstGradeScoresFormControl.setValidators(worstScoresSmallerThanBestScoresValidator(this.bestGradeScoresFormControl));

行为是一样的???

这里有什么问题?为什么更改worstScore控件将form.valid值从FALSE更改为TRUE?

export const bestScoresGreaterThanWorstScoresValidator = (worstScoreControl: FormControl): ValidatorFn => {
  return (control: FormControl): { [key: string]: boolean } => {
    if (control.value > worstScoreControl.value) {
      worstScoreControl.setErrors(null);
      control.setErrors(null);
    }
    else {
      worstScoreControl.setErrors({ "bestScoresGreaterThanWorstScores": true });
      return { 'bestScoresGreaterThanWorstScores': true };
    }
  };
}

export const worstScoresSmallerThanBestScoresValidator = (bestScoreControl: FormControl): ValidatorFn => {
  return (control: FormControl): { [key: string]: boolean } => {
    if (control.value < bestScoreControl.value) {
      bestScoreControl.setErrors(null);
      control.setErrors(null);
    }
    else {
      bestScoreControl.setErrors({ "worstScoresSmallerThanBestScores": true });
      return { 'worstScoresSmallerThanBestScores': true };
    }
  };
}

更新

我在这里放了一个插件来说明问题:

https://plnkr.co/edit/ygiVNtPImkMveLGogTk2?p=preview

在我看来,解决方案不能是我在整个Form上创建一个独特的自定义验证器,因为我希望所有的自定义验证都有自己的验证器类/函数。

如果你根据我的plunkr代码制作解决方案,那么赏金就是你的: - )

1 个答案:

答案 0 :(得分:0)

尽管没有像添加/删除角度表单控件错误的特定错误这样的功能,您可以自己实现它。

function addError(control: AbstractControl, errorKey: string) {
  const errors = control.errors || {};
  errors[errorKey] = true;

  control.setErrors(errors);
}

function removeError(control: AbstractControl, errorKey: string) {
  const errors = control.errors || {};
  delete errors[errorKey];

  control.setErrors(Object.keys(errors).length ? errors : null)
}

现在只需在自定义验证器中添加或删除错误:

<强> bestScoresGreaterThanWorstScoresValidator

export const bestScoresGreaterThanWorstScoresValidator = 
                              (worstScoreControl: FormControl): ValidatorFn => {
  return (control: FormControl): { [key: string]: boolean } => {

    if (control.value > worstScoreControl.value) {
      removeError(worstScoreControl, 'worstScoresSmallerThanBestScores')
      return null;
    }
    else {
      addError(worstScoreControl, 'worstScoresSmallerThanBestScores');
      return { 'bestScoresGreaterThanWorstScores': true };
    }

  };
}

<强> worstScoresSmallerThanBestScoresValidator

export const worstScoresSmallerThanBestScoresValidator = 
                               (bestScoreControl: FormControl): ValidatorFn => {
  return (control: FormControl): { [key: string]: boolean } => {

    if (control.value < bestScoreControl.value) {
      removeError(bestScoreControl, 'bestScoresGreaterThanWorstScores')
      return null;
    }
    else {
      addError(bestScoreControl, 'bestScoresGreaterThanWorstScores');
      return { 'worstScoresSmallerThanBestScores': true };
    }
  };
}

<强> ng-run example