【问题标题】:Angular2 reactive forms delete errorAngular2反应形式删除错误
【发布时间】:2017-09-12 16:58:34
【问题描述】:

我正在尝试将表单控件状态设置为有效

this.currencyForm.controls['currencyMaxSell'].setErrors({smallerThan: true})

现在我想删除这个错误。

【问题讨论】:

标签: angular angular2-forms


【解决方案1】:

只需将错误对象中的值设置为null

this.currencyForm.controls['currencyMaxSell'].setErrors({smallerThan: null})

或者,如果您想从控件中删除所有验证,请按照 cmets 中的建议使用 setErrors(null)

【讨论】:

【解决方案2】:

要在执行手动验证时仅删除一个表单控件错误,请执行以下操作:

this.myFormGroup.get('myControl').setErrors({'myCustomError':null})

这只会更新指定错误的值,并且不会删除您之前可能完成的任何验证,这与 setErrors(null) 不同,后者会使控件的整个错误对象无效。

【讨论】:

  • 我现在才看到这是从 2017 年 4 月开始的。希望它仍然有帮助。
  • 如果我需要以myFormGroup.controls.setErrors(null) 之类的形式消除所有控件的所有错误,是否有机会?
  • 对我来说,它使 FormControl 无效。
【解决方案3】:

AFAIK,当你可以创建custom validators 时,你真的不需要使用setErrors 方法。您可以轻松地为您的 formControl 或 formGroup 创建自定义验证器,并且在您的验证器中您只需要返回一个 ValidatorFn 并且您不应该使用 setErrors 方法。

有关 FormGroup 的自定义验证器的更多信息,我建议您阅读此 article,它解决了我的问题。

这是我的工作代码:

registerationForm = this.formBuilder.group({
  username: ['', [Validators.required, Validators.email]],
  passwords: this.formBuilder.group(
    {
      password: ['', Validators.required],
      confirmPassword: ['', Validators.required]
    },
    {
      validator: matchPassword
    }
  ),
  policyAgreement: ['', Validators.required]
});

// Outside my component:
const matchPassword = (group: FormGroup) => {
  const password = group.get('password').value;
  const confirmPassword = group.get('confirmPassword').value;
  return password != confirmPassword ? { matchPassword: true } : null;
};

【讨论】:

  • setErrors 在您想设置提交表单后从服务器返回的错误时很有用,我不确定在这些情况下是否可以使用自定义验证器。
  • 上面 matchPassword 的参数...应该是 FormGroup 类型吗?这是组级别的验证,不是吗?
【解决方案4】:

要仅删除一个表单控件错误,请使用 .setErrors() 和元素。

this.myFormGroup.get('myControl').setErrors(
)

这只会删除一个元素错误。

【讨论】:

  • setErrors() 函数不接受没有任何参数的调用。要重置错误,您必须通过 null :setErrors(null)。适用于 Angular v6
【解决方案5】:

其他解决方案似乎不起作用。只要errors属性不为null,angular就认为控件无效。

只要您只想删除一个错误并留下其他错误,除了手动之外别无他法。此函数将仅删除参数中指定的一个错误并保留其他错误。它还将确保如果您删除最后一个错误,该控件将变为有效。

// call it in validator function if control is valid
removeError(this.currencyForm.controls['currencyMaxSell'], 'smallerThan');

// this function removes single error
function removeError(control: AbstractControl, error: string) {
  const err = control.errors; // get control errors
  if (err) {
    delete err[error]; // delete your own error
    if (!Object.keys(err).length) { // if no errors left
      control.setErrors(null); // set control errors to null making it VALID
    } else {
      control.setErrors(err); // controls got other errors so set them back
    }
  }
}

// this function adds a single error
function addError(control: AbstractControl, error: string) {
  let errorToSet = {};
  errorToSet[error] = true;
  control.setErrors({...control.errors, ...errorToSet});
}

【讨论】:

  • 谢谢,它有效,但我认为 control.setErrors(err);没有必要,因为它设置的对象与已设置的对象相同。
  • 在 Angular 7 中完美运行。感谢您分享这个急需的功能。
【解决方案6】:

使用 Angular 7,这里提供的解决方案都不适合我。

我必须在与多个表单字段一起使用的自定义验证器中手动处理我的错误。

下面的示例检查两个表单域之间的差异是否足够大。有问题的表单字段也有多个其他验证器(lte,gte),因此使用 setError(null) 清除所有错误是不可能的,并尝试使用 删除我的特定错误setError({minDifference: null}) 总是让 formControl 处于无效状态。

minDifference(firstKey: string, secondKey: string, minDifference: number) {
  return (c: AbstractControl): {[key: string]: any} => {
    if (!c.get(firstKey).value || !c.get(secondKey).value ||
      Math.abs(c.get(firstKey).value - c.get(secondKey).value) >= minDifference) {
      // If there is only one error and it's this one then remove all errors from the control (removing 1 does not work)
      if (c.get(secondKey).hasError('minDifference')) {
        // If previously our error has been set, remove it.
        delete c.get(secondKey).errors.minDifference;
        // If no errors remain after, set the control to be valid.
        if (Object.keys(c.get(secondKey).errors).length === 0) {
          c.get(secondKey).setErrors(null);
        }
      }
      return null;
    }
    // Condition was not met, add our error to the alreadying existing ones.
    c.get(secondKey).setErrors( {...c.get(secondKey).errors, ...{ minDifference: true}} )
  }
}

说实话,我不太喜欢我的解决方案,我希望能够更简单地解决这个问题,但找不到解决方法。

【讨论】:

    【解决方案7】:

    如果您手动设置错误,您可以使用 setValue() 将其再次变为有效。

    if(myCurrency is smallerThanOther){
     this.currencyForm.controls['currencyMaxSell'].setErrors({smallerThan: true})
    } else {
     this.currencyForm.controls['currencyMaxSell'].setValue(myCurrency);
    }
    

    【讨论】:

    • 这对我不起作用,设置值后错误仍然存​​在。
    【解决方案8】:

    您需要将此处的最佳答案和 cmets 中的答案混合在一起,以使您的表单消除错误并生效以重新提交:

    if (this.currencyForm.hasError("smallerThan")) {
     this.currencyForm.setErrors({
      "currencyMaxSell": null
      });
      this.currencyForm.updateValueAndValidity();
    }
    

    如果错误出现在表单上的特定控件上,则包括表单控件:

    if (this.currencyForm.controls.currencyMaxSell.hasError("smallerThan")) {
     this.currencyForm.setErrors({
      "currencyMaxSell": null
      });
      this.currencyForm.updateValueAndValidity();
    }
    

    【讨论】:

      【解决方案9】:

      试试这个:

      const value = this.currencyForm.controls['currencyMaxSell'].value;
      this.currencyForm.controls['currencyMaxSell'].patchValue();
      this.currencyForm.controls['currencyMaxSell'].patchValue(value);
      

      您必须实际更改一次值,因此 fromControl 将重新检查它是否有效。

      【讨论】:

        【解决方案10】:

        除了@karoluS 所建议的,您可以简单地使用:

        delete control.errors.errorName;
        

        所以在你的情况下:

        delete this.currencyForm.controls['currencyMaxSell'].errors.smallerThan;
        

        【讨论】:

          【解决方案11】:

          清除单个表单控件上的错误

          this.myFormGroup.get('myControl').reset() 
          

          清除所有表单控件上的错误

          this.myFormGroup.reset() 
          

          注意:这也会重置您的控件。所以你可以用

          this.myFormGroup.get('myControl').setValue(myValue) 
          

          将值设置为您想要的任何值,但没有错误。

          【讨论】:

            【解决方案12】:

            此函数添加和删除单个错误

                manageErrors(whatToDo: 'add' | 'remove', control: AbstractControl, err: string) {
            
                    const errors = control.errors; // get control errors
            
                    if (whatToDo === 'add') { // add errors
            
                      // add your new error
                      if (errors) {
                        errors[err] = true;
                        control.setErrors(errors);
                      } else {
                        control.setErrors({ [err]: true });
                      }
            
                    } else if (whatToDo === 'remove') { // remove errors
            
                      if (errors) {
                        // delete your error
                        delete errors[err];
            
                        // If any errors are left
                        if (Object.keys(errors).length) {
                          control.setErrors(errors); // controls got other errors so set them back
                        } else {
                          control.setErrors(null); // set control errors to null (making it VALID)
                        }
                      }
                    }
                  }
            

            【讨论】:

              【解决方案13】:

              要从ValidatioErrors 对象中删除error,有一些选项:

              1) 全部清除

              这会从元素中删除所有错误。 setErrors 将更新控件状态的有效性,因此您不必(大部分时间)。

              警告:您需要传递 null,因为在没有值的情况下调用它会导致不良结果。

              此外,如果此控件上有其他验证错误,您也只需将其删除。

                mycontrol.setErrors(null);
              

              2) 设置为空

              将错误设置为 null 是一种选择。但是,当您检查 mycontrol.errors 时,错误仍然存​​在。如果不是预期的效果,这可能会导致副作用。

                mycontrol.setErrors({ myError: null});
              

              3) 彻底删除

              这有点复杂,但过程很简单。检测、删除和重新评估。

                if (mycontrol.hasError('sharedValue')) {
                  delete mycontrol.errors.sharedValue;
                  mycontrol.updateValueAndValidity({ onlySelf: true});
                }
              

              结论

              您使用哪一个真正取决于您的用例。我更喜欢第 3 种解决方案,因为它使我的任何自定义验证器明确设置错误,而不是隐含地,以非常相似的方式运行。

              1) 当您确定您的错误是控件上唯一的错误时使用此选项

              2) 当你想修改错误时使用这个,但是将它设置为一个特定的值

              3) 当您想删除错误而不影响代码执行时控件上可能出现的任何其他错误时,请使用此选项

              【讨论】:

                【解决方案14】:

                使用可以使用下面提到的方法。这将设置或删除特定控件中的错误。

                errorInFields(control: AbstractControl,key,value){
                let errors  = control.errors;
                if(!errors){
                  if(value == null){
                    control.setErrors(null);
                  }else{
                    let error = {};
                    error[key] = value;
                    control.setErrors(error);
                  }
                }else{
                
                  if(value == null){
                    if(errors.hasOwnProperty(key)){
                      delete errors[key];
                    }
                    let errorsKey = Object.getOwnPropertyNames(errors);;
                    if(errorsKey.length <= 0){
                      control.setErrors(null);
                    }else{
                      control.setErrors(errors);
                    }
                  }else{
                    errors[key] = value;
                    control.setErrors(errors);
                  }
                }
                }
                

                【讨论】:

                  【解决方案15】:

                  正如这里提到的discussion。目前没有“正确”的方法来做到这一点。因为期望的行为不是最终的。 但是您可以使用这个方便的解决方法来解决这个问题:

                  if ( control.hasError('errorToRemove') ) { // this validation is optional, I think
                    const { errorToRemove, ...errors } = control.errors;
                    control.setErrors(errors);
                    control.updateValueAndValidity();
                  }
                  

                  学分Jose Salazar

                  【讨论】:

                    猜你喜欢
                    • 2017-09-14
                    • 2017-12-22
                    • 2017-11-22
                    • 2017-11-02
                    • 2022-01-18
                    • 2017-02-11
                    • 2017-04-29
                    • 2017-08-22
                    • 2017-05-05
                    相关资源
                    最近更新 更多