简体   繁体   English

Angular 异步验证器 - 使用响应数据

[英]Angular async validator - work with response data

I'm struggling with angulars async validators.我正在与角度异步验证器作斗争。

I created a async validator, which checks if an article number is existent.我创建了一个异步验证器,用于检查商品编号是否存在。 The service returns a response object, including detailed information about my article.该服务返回一个响应对象,包括关于我的文章的详细信息。

Currently I'm trying to implement the Container/Presentational Components architecture.目前我正在尝试实现容器/展示组件架构。 My form should only receive the async validator from the container component.我的表单应该只接收来自容器组件的异步验证器。

My problem is, that parts of my form are only shown, if the validation of article number is valid.我的问题是,如果文章编号的验证有效,我的部分表格只会显示。 The rest of the application is filled with data from the response of the async validation.应用程序的其余部分填充了来自异步验证响应的数据。

This works, when using the logic inside my presentational component, but I don't think this is the right way.这在我的展示组件中使用逻辑时有效,但我认为这不是正确的方法。 It would be better, if I would give my presentational component the data via property binding and receive the data of the async validation inside my container component.如果我通过属性绑定向我的展示组件提供数据并在我的容器组件中接收异步验证的数据,那会更好。

Is this the right way, if yes, how?这是正确的方法吗,如果是,怎么做? Or should I create a request only for the async validation and fetch the data seperatly, after the field is valid?或者我应该只为异步验证创建一个请求并在字段有效后单独获取数据?

Currently my validator looks like this:目前我的验证器看起来像这样:

  private checkArticleNrValidator(
    ctrl: AbstractControl
  ): Observable<ValidationErrors | null> {
    return this.ps.getArticle(+ctrl.value).pipe(
      tap(d => this.article = +d.Data.Artikel),
      map(() => null),
      catchError(e => of({ articleNrError: e }))
    );
  }

and is used inside my presentational component like this并像这样在我的展示组件中使用

articleNr: [
  '',
  [Validators.required, Validators.pattern(/^([0-9]{5})$/)],
  this.checkArticleNrValidator.bind(this) <---
],

What is the way to seperate this logic?分离这个逻辑的方法是什么? Or is this overall a wrong approach.或者这总体上是一种错误的方法。

Theorically Presentational Components are used to receive (@Input) and display data / trigger events (@Output).理论上表示组件用于接收(@Input)和显示数据/触发事件(@Output)。

So In your case I'd move that 'checkArticleNrValidator' logic outside your presentational component, for example in the container (if that causes a circular dependency between container and presentational components just move it to a new ts file like blablabla.validators.ts and implement the logic there inside an export function)因此,在您的情况下,我会将“checkArticleNrValidator”逻辑移到您的展示组件之外,例如在容器中(如果这导致容器和展示组件之间存在循环依赖,只需将其移动到新的 ts 文件中,例如 blablabla.validators.ts 和在导出函数中实现逻辑)

PS: I Guess your ps variable is a service. PS:我猜你的 ps 变量是一个服务。 Let's call it PService.我们称它为 PService。

export function checkArticleNrValidator(ps: PService): AsyncValidatorFn {
   return (control: AbstractControl): Observable<ValidationErrors | null> => {
      return ps.getArticle(control.value)
             .pipe(
                 tap(d => this.article = +d.Data.Artikel),
                 map(() => null),
                 catchError(e => of({ articleNrError: e}))
             );
   }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM