访问ngrx Observable中的变量始终返回undefined

时间:2016-07-22 05:36:41

标签: angular angular2-forms typescript1.8 ngrx

我有以下内容:

language.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
        })

 ....
    }

定制validator.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变量总是未定义的。

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

由于

1 个答案:

答案 0 :(得分:0)

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

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

  msg = doGetErrorMsg(ctrlErrors);

  return msg

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

您应该为控件使用异步验证器,并使其返回promise。像这样:

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) => {
                });
        });
    }
}