【问题标题】:async pipe inside ngIf still gets valuengIf 中的异步管道仍然获得价值
【发布时间】:2021-01-18 19:31:24
【问题描述】:

我想编写一个可折叠的组件,它有一个“展开”按钮,可以打开一个项目列表。这个列表是通过网络请求创建的,我想知道这个请求什么时候发生 - 因为据我了解,async 管道就像一个订阅,ngIf 会导致组件订阅被重新创建,我希望请求的值只能使用一次,但是每次我“显示”扩展器时都会创建它。

StackBlitz minimal example

在我的AppComponent 里面我有这样的逻辑:

  data$ = of('expensive data from server').pipe(
    take(1),
    tap(() => console.log('data from server emit!')),
    // shareReplay(1),
    finalize(() => console.log('complete!'))
  );
  showSon = true;

模板是这样的:

<button (click)="showSon=!showSon">Click me!</button>
<p *ngIf="showSon">
  <ng-container *ngIf="data$ | async as data">
    <div>{{data}}</div>
  </ng-container>
</p>

我的理解是,由于 observable 是通过 of 创建的,因此它应该触发其值一次然后完成,并由控制台日志确认。然而令我惊讶的是,每次我在ngIf 中显示元素时,即使async 现在订阅了一个不是ReplaySubject 的完整可观察对象,我仍然会得到一个值。

我认为使用 shareReplay(1) 可以解决发出多个 Web 请求的问题,但我仍然不明白,每当重新创建 ngIf 中的模板时,一次性 observable 是如何重复可用的。

【问题讨论】:

  • 每当 If 为真时,元素都会被重新创建.. 所以异步管道重新订阅 data$ observable 导致它再次发射..

标签: angular rxjs rxjs-observables


【解决方案1】:

MikeOne 的评论是正确的。 Everytime the If is true, the element gets recreated.. so the async pipe re-subscribes to the data$ observable causing it to emit again..

您的解决方案也是正确的,使用shareReplay(1),就像您提到的那样。

【讨论】:

    猜你喜欢
    • 2018-10-11
    • 1970-01-01
    • 2017-01-04
    • 2022-08-11
    • 2019-11-25
    • 2020-08-24
    • 2018-05-03
    • 2016-06-24
    • 1970-01-01
    相关资源
    最近更新 更多