1

我有以下内容:

语言.component.ts

form: FormGroup;
first: AbstractControl;
second: AbstractControl;

  constructor(private _fb: FormBuilder) {
    this.first =
        new FormControl('', [Validators.required, Validators.minLength(2), CustomValidators.nounValidator])
    this.second = new FormControl('', [CustomValidators.nounValidatorOptional])
  }

  ngOnInit() {
    this.form = this._fb.group(
        {

          first: this.first,
          second: this.second
        });

    const errors$ = Observable.fromPromise(validate(this.language));
    this.first.valueChanges
        .subscribe(
        value => {
            let msg = onPropertyValueChanged(this.language, this.first, this.first.errors)
          console.log('MSG| ', msg) // ALWAYS RETURNED UNDEFINED
        })

 ....
    }

自定义验证器.ts

export function onPropertyValueChanged(
    data: any, ctrl: AbstractControl, ctrlErrors: IStringMap): string {
  console.log('FORM-ERRORS|', jsonStringify(ctrlErrors));

  let msg = null;
  const errors$ = Observable.fromPromise(validate(data));
  errors$
      .filter(errors => errors.length > 0)
      .subscribe(
          errors => {
            errors.map(
                error => {
                  msg = doGetErrorMsg(error)
                })
          })

  msg = doGetErrorMsg(ctrlErrors);


  return msg
}

function doGetErrorMsg(errors: IStringMap | ValidationError): string {
  const errorKeys = ['matches', 'maxLength', 'minLength', 'required'];
  let msg = null;

  if (errors instanceof ValidationError && errors != null) {
    for (let key of errorKeys) {
      console.log('KEY', key);
      console.log('matches ', errors.constraints['matches']);
      console.log('hasOwnProperty', errors.constraints.hasOwnProperty(key));

      // class-validator generated errors
//      if (errors.hasOwnProperty(key)) {
      switch (key) {
        case 'matches':
          msg = errors.constraints['matches'];
          break;

        case 'maxLength':
          msg = errors.constraints['maxLength'];
          break;

        case 'minLength':
          msg = errors.constraints['minLength'];
          break;
//        }
      }
    }
  }
  else {
    for (let key of errorKeys) {
      // angular built-in validator errors
      if (errors != null) {
        switch (key) {
          case 'matches':
            msg = errors[key];
            break;

          case 'maxLength':
            msg = errors[key];
            break;

          case 'minLength':
            msg = errors[key];
            break
        }
      }
    }
  }
  return msg
}

尽管错误是由 onPropertyChanged() 生成的,但在 language.component.ts 中分配值的 msg 变量始终未定义。

我该如何纠正?任何帮助表示赞赏。

谢谢

4

1 回答 1

0

我认为您的问题是您如何在此处设置消息:

errors$
      .filter(errors => errors.length > 0)
      .subscribe(
          errors => {
            errors.map(
                error => {
                  msg = doGetErrorMsg(error)
                })
          })

  msg = doGetErrorMsg(ctrlErrors);

  return msg

我认为这将始终返回 null 作为“msg = doGetErrorMsg(ctrlErrors);” 在订阅完成设置您的消息之前执行。

您应该为您的控件使用异步验证器,并使其返回一个承诺。像这样的东西:

this.first =
        new FormControl('',
Validators.compose([Validators.required, Validators.minLength(2), CustomValidators.nounValidator]),
Validators.composeAsync([(control: Control) => this.IsValid(control.value)])
        );

public IsValid(id: string): Promise<any> {
    if (id.length > 2) {
        return new Promise(resolve => {
            this.GetPartById(id)
                .subscribe((data: Part) => {
                    if (!data) {
                        resolve({dataExists: false});
                    } else {
                        // need to return null if ok
                        resolve(null);
                    }
                }, (error: any) => {
                });
        });
    }
}
于 2016-07-22T15:53:18.630 回答