Angular 6 error: ValidatorFn expected to return a promise

Angular 6 error: ValidatorFn expected to return a promise

我遇到了一个问题,验证器函数期望 return 一个承诺。据我了解,我正在创建一个自定义验证器函数,使用承诺检查输入的 "New Password" 字符串是否等于 "ConfirmPassword" 字符串。这是我的代码的当前状态:

变化-password.component.ts

import { FormBuilder, FormGroup, Validators, AbstractControl } from '@angular/forms';
import { passwordValidator } from './password.validator';

export class ChangePasswordComponent implements OnInit {

  form: FormGroup;

  constructor(formCreator: FormBuilder) { 

    this.form = formCreator.group({
    oldPassword: ['', [ Validators.required, Validators.minLength(4) ], passwordValidator.isSameOld],
    newPassword: ['', [ Validators.required, Validators.minLength(4)] ],
    confirmPassword: 
                 ['', [ Validators.required, Validators.minLength(4)], 
                        passwordValidator.isSameNew ] 
    });
  }

password.validator.ts

在 Jaime 的帮助下添加的内容

    import { AbstractControl, ValidationErrors, FormControl, ValidatorFn } from "@angular/forms";

    static isSameNew(formFields: FormGroup) : Promise<ValidationErrors | null>{ 
        return new Promise((resolve, reject) => {

            setTimeout(() => {
                console.log(formFields.get('newPassword'));

                if (formFields.get('confirmPassword').value !== formFields.get('newPassword').value) {
                    console.log(formFields);

                    resolve({isSameNew: true});
                }

                else resolve(null);
            }, 2000)

        });
    }

你能帮我调试一下吗?我尝试通过编写

将 newPassword 传递给函数
    confirmPassword: 
                 ['', [ Validators.required, Validators.minLength(4)], 
                        passwordValidator.isSameNew(newPassword) ] 

但很快发现我不能这样做,因为 newPassword 属性 直到定义表单对象后才定义。我需要使用一个 promise,这样我就可以使用一个异步回调函数来延迟 'password mismatch' 错误消息出现,以避免让用户吃惊。

非常感谢您的宝贵时间

如果您想比较两个不同控件的值,您应该将验证器附加到 group 而不是其中一个控件。

尝试这样的事情:

  // Your component constructor:
  constructor(formCreator: FormBuilder) { 
    this.form = formCreator.group(
      {
        oldPassword: ['', [ Validators.required, Validators.minLength(4) ]],
        newPassword: ['', [ Validators.required, Validators.minLength(4)] ],
        confirmPassword: ['', [ Validators.required, Validators.minLength(4)], passwordValidator.isSameNew ] 
      },
      {
        validator: PasswordMatchValidator
      }
    );
  }

  // password-match.validator.ts:
  export function PasswordMatchValidator(formGroup: FormGroup): void {
    const newPassword = formGroup.get('newPassword').value;
    const confirmPassword = formGroup.get('confirmPassword').value;

    formGroup.get('confirmPassword').setErrors(undefined);

    if (newPassword !== confirmPassword) {
      formGroup.get('confirmPassword').setErrors({ match: true });
    }
  }

您可以使用相同的方法比较新旧密码并相应地设置isSameNew

另请注意,如果您想要 return 承诺,您应该使用 AsyncValidatorFn interface instead of ValidatorFn 界面。

我最终通过像这样调用 formFields 的根方法解决了这个问题:

    static isSameNew(formFields: FormGroup) : Promise<ValidationErrors | null>{ 
    return new Promise((resolve, reject) => {

        setTimeout(() => {

            if (formFields.root.get('confirmPassword').value !== formFields.root.get('newPassword').value) {
                resolve({isSameNew: true});
            }

            else resolve(null);
        }, 2000)

    });

我不完全知道为什么使用 "root" 解决了我的问题,但据我所知,每个 FormGroup 都知道其父 Form 的控件