【问题标题】:Call Async functions (Retunes Observable) from HTML template从 HTML 模板调用异步函数(Retunes Observable)
【发布时间】:2019-03-04 09:55:25
【问题描述】:

HTML 模板上显示的数据是 Key 表单数据。意思是,它需要翻译。 为此,我想从我的模板中调用一个异步函数。试过了,没有成功:

模板:

<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")

而且效果很好。

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

【问题讨论】:

  • 您面临的具体问题是什么?
  • 举个例子。比如你试图显示的整个对象,并提到显示的是什么键而不是你想要显示的?。
  • 我的浏览器卡住了。它进入一个无限循环调用这个函数......我试过只返回一个可观察的(使用(“some”字符串“))并且它工作正常。当传递一个保存为局部变量的可观察时,会发生这个循环。
  • 显示 servingStylesData 函数
  • @SachilaRarawaka 编辑了我的问题,并添加了 servingStylesData

标签: javascript angular typescript rxjs


【解决方案1】:

tl;博士 不要将异步管道与函数调用一起使用。这是昂贵且长期运行的,并且可能会破坏用户体验或在您的情况下使您的浏览器崩溃:您自己管理您的 observables,而不是使用 易于使用 async 管道。

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


请注意 Angulars 生命周期系统的工作原理。

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

这对于管道来说尤其糟糕,而对于异步管道来说最糟糕。如果我们称您使用 async 管道昂贵且运行时间长,Angular 表示:

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

或者在你的情况下使浏览器崩溃。

请找this blog post作进一步解释。

【讨论】:

  • 感谢您的回答,它确实让事情变得更清楚了。话虽如此,我已经在使用 ChangeDetectionStrategy.OnPush,所以不确定我的函数为什么会被调用。你有什么建议呢?有没有可能从 Template 传递值并异步操作?
  • 你能创建一个stackblitz吗?我缺少进一步解决此问题的上下文。
  • 好的,我通过接受It's not best practice to use a function that retunes and observable来解决了这个问题。并创建了一个 Observable ,其中包含模板使用变量所需的所有值。接受这个答案,tnx
  • 很好的解决方案。否则,您可以手动处理订阅,而不是使用 async 管道。但是如果没有堆栈闪电战,我无法向您展示这个解决方案。
猜你喜欢
  • 2022-12-07
  • 1970-01-01
  • 2019-12-19
  • 2018-07-27
  • 1970-01-01
  • 2020-09-29
  • 2020-04-20
  • 1970-01-01
  • 2020-08-29
相关资源
最近更新 更多