【问题标题】:FormBuilder group is deprecated with validatorFormBuilder 组已弃用验证器
【发布时间】:2021-04-25 02:38:37
【问题描述】:

我有类似的问题:

How do I resolve the error I am encountering using custom Validator syntax?

FormBuilder group is deprecated

我已阅读问题,但问题仍然出现在 linter 中:

group 已弃用:此 API 不是类型安全的,可能会导致问题 使用闭包编译器重命名。使用FormBuilder#group 重载 用AbstractControlOptions 代替。注意 AbstractControlOptions 期望 validatorsasyncValidators 到 成为验证者。如果您有自定义验证器,请确保它们的 验证函数参数是 AbstractControl 而不是 子类,例如FormGroup。这些函数将被调用 AbstractControl 类型的对象,不能自动 向下转换为子类,因此 TypeScript 将此视为错误。为了 例如,更改(group: FormGroup) => ValidationErrors|null 签名为(group: AbstractControl) => ValidationErrors|null。 (弃用)

这是我的 formBuilder:

registerForm = this._fb.group({
        firstname: ["", [Validators.required]],
        lastname: ["", [Validators.required]],
        email: ["", [Validators.required, Validators.email]],
        password: ["", [PasswordValidator.strength]],
        confirmPassword: ["", [Validators.required]]
    }, {
        validator: PasswordValidator.confirmed("password", "confirmPassword")
    });

还有我的验证器:

export class PasswordValidator {
    static confirmed = (controlName: string, matchingControlName: string) => {
        return (formGroup: FormGroup) => {
            const control = formGroup.controls[controlName];
            const matchingControl = formGroup.controls[matchingControlName];

            if (matchingControl.errors && !matchingControl.errors.confirmedValidator) {
                return null;
            }

            if (control.value !== matchingControl.value) {
                matchingControl.setErrors({ confirmedValidator: true });
                return ({ confirmedValidator: true });
            } else {
                matchingControl.setErrors(null);
                return null;
            }
        };
    }
}

知道为什么吗?我正在返回正确的对象。 :/

【问题讨论】:

  • validators 而不是validator
  • 修正错字(删除括号)。但这不是原因
  • 我的意思是由于validator: PasswordValidator.confirmed("password", "confirmPassword")这一行而引发了错误
  • 嗯,是的,我知道,但是,我该如何解决呢?
  • 只需添加一个... validators: [PasswordValidator.confirmed("password", "confirmPassword")]

标签: angular typescript angular-reactive-forms


【解决方案1】:

@OwenKelvin 部分正确。在 formBuilder 中它必须是 validators 而不是 validator,即使它只是一个验证器,再次抱歉 Owen。

但第二个问题出在验证器中。该函数应该接收AbstractControl 而不是FormGroup。所以下面的代码是正确的:

export class PasswordValidator {
    static confirmed = (controlName: string, matchingControlName: string) => {
        return (control: AbstractControl): ValidationErrors | null => {
            const input = control.get(controlName);
            const matchingInput = control.get(matchingControlName);

            if (input === null || matchingInput === null) {
                return null;
            }

            if (matchingInput?.errors && !matchingInput.errors.confirmedValidator) {
                return null;
            }

            if (input.value !== matchingInput.value) {
                matchingInput.setErrors({ confirmedValidator: true });
                return ({ confirmedValidator: true });
            } else {
                matchingInput.setErrors(null);
                return null;
            }
        };
    }
}

【讨论】:

    【解决方案2】:

    你在哪里得到错误?我做了一个stackblitz with your code,但我看不到它

    顺便说一句,我不太喜欢使用 setError 将错误“放入”控件中。

    如果你没有使用 mat-error,你可以简单地询问 form.errors。

    如果你使用 mat-error 你可以

    【讨论】:

    • 您没有错误,因为在您的 stackblitz 中您使用了validators。不幸的是,OP 坚持使用 validator,单数,因为他们只有 1 个验证器
    【解决方案3】:

    在链接的解决方案中,没有一个建议的答案对我有用...这就是它对我有用的方式:

    这就是验证器(包括自定义验证器)的调用方式:

     this.form = this.fb.group(
          {
          Password:                  ['', { validators:[ Validators.required, Validators.minLength(4)]}],
          ConfirmPassword:           ['', { validators:[ Validators.required, Validators.minLength(4)]}]
          },
          {validators: this.matchingPasswords('Password', 'ConfirmPassword')}
        )
    

    这是被调用的验证器(在这种情况下放置在同一个组件中)

    matchingPasswords(Password: string, ConfirmPassword: string) {
        return (controls: AbstractControl) => {
          if (controls) {
            const Password = controls.get('Password')!.value;
            const ConfirmPassword = controls.get('ConfirmPassword')!.value;
            //console.log ("check what is passed to the validator", password, confirmPassword);
            if (Password !== ConfirmPassword) { 
              //this is an error set for a specific control which you can use in a mat-error
              controls.get('ConfirmPassword')?.setErrors({not_the_same: true});  
              //this is the returned error for the form normally used to disable a submit button
              return {mismatchedPassword: true}  
            }
          }
          return null;
        }
      }
    
       
    
    • 验证功能无需(正如我在某些线程中所读)位于单独的模块中
    • 无需将验证器调用声明为“作为 AbstractControlOptions”。 (反而会阻止它工作)

    注意:

    1. 调用的是验证器而不是验证器
    2. 值是通过 .get 提取的,需要 !确认我们确定它们不为空
    3. 验证器必须返回 ValidationError 或 null

    【讨论】:

    • 这是 Angular 12 的正确答案。只需将“validator:”更改为“validators:”即可让已弃用的消息消失。
    猜你喜欢
    • 2021-03-17
    • 2021-04-12
    • 2017-10-23
    • 2018-09-08
    • 1970-01-01
    • 1970-01-01
    • 2021-02-09
    • 1970-01-01
    相关资源
    最近更新 更多