从HTML模板调用异步功能(可观察到的Retunes)

时间:2019-03-04 09:55:25

标签: javascript angular typescript rxjs

HTML模板上显示的数据是“密钥表单”数据。意思是,它需要翻译。 为此,我想从模板中调用Async函数。尝试了这个但没有成功:

模板:

<span class="myClass-rowValue">{{translateServingStyle(size.defaultServingStyle?.surcharge) | async}}</span>

组件ts文件:

servingStylesData$: Observable<ServingStyles_servingStyles[]>;

ngOnInit(): void {
    this.servingStylesData$ = of(this._apollo
      .watchQuery<ServingStyles>({
        query: ServingStylesQuery
      }))
      .pipe(
        filter((query) => !!query),
        switchMap((query) => query.valueChanges),
        take(1),
        takeUntil(this._ngOnDestroy),
        map((response) => response.data.servingStyles)
      );
}

translateServingStyle(servingStyleValue: string): Observable<string> {
    return this.servingStylesData$
      .pipe(
        map((servingStyles) => servingStyles
          .filter((servingStyle) => servingStyle.value === servingStyleValue)
          .map((selectedServingStyle) => selectedServingStyle.value)[0]
          )
      );
  }

目前这样做的原因是什么?

#修改

这使我的浏览器崩溃。 进入无限循环,调用 translateServingStyle()

我尝试删除我的功能代码,而只是返回

of("some string")

它工作正常。

但是,当将管道引用到局部变量时,会发生此循环。谁能解释为什么?

1 个答案:

答案 0 :(得分:3)

tl; dr 不要在函数调用中使用异步管道。这是昂贵且长期运行的操作,可能会破坏用户体验,或者导致您的浏览器崩溃:您可以自己管理可观察对象,而不必使用易于使用 async管道。

如果您仍想将async管道与功能一起使用,则可以尝试使用ChangeDetectionStrategy.OnPush。这带来了其他缺点,例如手动运行更改检测,例如this.cdr.detectChanges();cdr的类型为ChangeDetectorRef


请注意Angulars Lifecycle系统的工作原理。

由于评估的函数值没有内部引用(Angular用于检查值是否已更改或需要更新),因此生命周期钩子ngOnChanges不会检查它们,而是使用{ {1}},运行很多次

这对于管道尤为严重,而对于异步管道则更为严重。如果我们称您使用ngDoCheck管道昂贵且运行时间长,Angular指出:

  

昂贵且运行时间长的管道可能会破坏用户体验

或者您的情况导致浏览器崩溃。

请找到this blog post以获得进一步的说明。