ng内部的异步管道如果仍然有价值

问题描述

我想编写一个具有“展开”按钮的可折叠组件,该按钮可打开项目列表。该列表是通过Web请求创建的,我想知道何时发生此请求-因为据我了解,#:import utils kivy.utils #: import Window kivy.core.window.Window <FlatButton@ButtonBehavior+Label>: font_size: 14 <PosWindow>: id: main_win orientation: 'vertical' canvas.before: Color: rgb: utils.get_color_from_hex('#ffffff') Rectangle: size: self.size pos: self.pos BoxLayout: spacing: 0 orientation: 'vertical' #THE BEGINNNING OF THE TOP BAR BoxLayout: size_hint_y: None height: 30 Label: text: 'HEADER POSITION' size_hint_x: .6 bold: True color: (1,1,1) canvas.before: Color: rgb: utils.get_color_from_hex('#5B2437') Rectangle: size: self.size pos: self.pos Label: text: 'The Name' size_hint_x: .4 height: 30 bold: True color: (1,1) canvas.before: Color: rgb: utils.get_color_from_hex('#5B2437') Rectangle: size: self.size pos: self.pos # THE END OF THE TOP BAR #THE BEGINNING OF THE SECOND WAVE FULL BoxLayout: id: current size_hint_y: None height: 50 canvas.before: Color: rgba: (1,1) Rectangle: size: self.size pos: self.pos Button: text: 'Current Item:' background_normal: '' background_color: (.06,.32,1) size_hint_x: .4 Button: id: cur_product text: 'Default Product' background_normal: '' background_color: (.06,.4,1) Button: id: cur_price text: '0.00' background_normal: '' background_color: (.06,.65,1) size_hint_x: .2 Widget: #To place everything at the top of the screen #THE END OF THE SECOND WAVE FULL #SEARCH FOR A PRODUCT BoxLayout: id: current orientation: 'horizontal' size_hint_y: None height: 50 canvas.before: Color: rgba: (1,1) Rectangle: size: self.size pos: self.pos BoxLayout: size_hint_x: .4 id: searchBox canvas.before: Color: rgba: (.06,.75,.35,1) Rectangle: size: self.size pos: self.pos BoxLayout: size_hint_x: .6 id: previewBox canvas.before: Color: rgba: (.06,.85,1) Rectangle: size: self.size pos: self.pos Widget: 管道就像是订阅,而async会导致重新创建组件订阅,我希望请求的值只能使用一次,但是每次我“展示”扩展器时都会创建该请求。

StackBlitz minimal example

在我的ngIf中,我有以下逻辑:

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> 创建的,因此它应该触发一次其值,然后将其触发,并由控制台日志确认。但是,令我感到惊讶的是,每次显示of内的元素时,即使ngIf现在订阅的不是async的完整可观察对象,我仍然得到一个值。 / p>

我认为使用ReplaySubject可以解决发出多个Web请求的问题,但是我仍然不知道无论何时shareReplay(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)