简体   繁体   English

ngIf 内的异步管道仍然有价值

[英]async pipe inside ngIf still gets value

I want to write a collapsible component which has an "Expand" button that opens a list of items.我想编写一个可折叠组件,它有一个“展开”按钮,可以打开项目列表。 This list is created through a web request, and I'm wondering when this request happens - since to my understanding the async pipe is like a subscription and the ngIf would cause the component subscribing to be recreated, I would expect the value of the request to only be available once, however it is created each time I 'show' the expander.此列表是通过 Web 请求创建的,我想知道此请求何时发生 - 因为据我了解, async管道就像订阅,而ngIf会导致重新创建组件订阅,我希望请求的值只能使用一次,但是每次我“显示”扩展器时都会创建它。

StackBlitz minimal example StackBlitz 最小示例

Inside my AppComponent I have this logic:在我的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;

The template is like this:模板是这样的:

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

My understanding is that since the observable is created via of , that it should fire its value once and then complete, confirmed by the console logs.我的理解是,由于 observable 是通过of创建of ,它应该触发它的值一次然后完成,由控制台日志确认。 However I'm surprised that every time I show the element inside the ngIf , I still get a value even though async is now subscribing to a completed observable that is not a ReplaySubject .然而,令我惊讶的是,每次我在ngIf显示元素时,即使async现在订阅了一个不是ReplaySubject的完整可观察ngIf ,我仍然得到一个值。

I think using shareReplay(1) would solve the issue of making multiple web requests, but I still don't understand how the single-use observable is repeatedly available whenever the template inside the ngIf is recreated.我认为使用shareReplay(1)可以解决发出多个 Web 请求的问题,但我仍然不明白,每当重新创建ngIf的模板时,一次性使用的 observable 是如何重复可用的。

MikeOne's comment is correct. 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..

Your solution is also correct, to use shareReplay(1) as you've mentioned.您的解决方案也是正确的,可以使用您提到的shareReplay(1)

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

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