ngIf指令中的异步管道

时间:2020-05-18 08:14:26

标签: angular rxjs observable

AsyncPipe内使用*ngIf时,如果连接到Observable的{​​{1}}在AsyncPipe变为真之前推送其值,则该值从*ngIf返回的信息将不正确。

例如,假设我有:

AsyncPipe

然后说事件按此顺序发生:

  1. <div *ngIf="showPipe"> <div *ngFor="let item of arrObs | async">{{item}}</div> </div> 是错误的
  2. showPipe推动[1,2,3]
  3. arrObs设置为true

从我所见,showPipe的行为就像*ngFor返回null一样。

解决此问题的一种方法是改用arrObs | async,但是[hidden]有很多好处,例如性能和使null处理更容易。

执行此操作的正确方法是什么?我是否应该完全不使用可观察对象来显示内容?我以为使用可观察的方法是最Angular-y的工作方式。

编辑: 我可观察到的实际上只是一个*ngIf,我称之为new Subject()

3 个答案:

答案 0 :(得分:3)

有一些方法可以解决此问题。我建议在您的shareReplay上添加一个Observable运算符:

readonly arrObs = this.someDataFromSomewhere().pipe(
  shareReplay(1)
);

如果您的Observable实际上是Subject,您也可以将其更改为BehaviorSubjectReplaySubject

这样,您将始终获得有关订阅的最新数据。

还有一些方法可以在模板中处理并保持*ngIf的好处:

<ng-container *ngIf="arrObs | async as arr">
  <div *ngIf="showPipe">
    <div *ngFor="let item of arr">{{item}}</div>
  </div>
</ng-container>

或者如果您不希望*ngIf等待可观察的情况

<ng-container *ngIf="{ arr: arrObs | async } as data">
 <div *ngIf="showPipe">
   <div *ngFor="let item of data.arr">{{item}}</div>
 </div>
</ng-container>

答案 1 :(得分:2)

在包含异步管道的ng-container中包围结构,并使用as将值存储在变量中。另外,仅在您在该异步管道中获取值之后,才使用ng-if指令加载容器。

<ng-container *ngIf="( arrObs| async ) as array">
    <div *ngIf="showPipe">
        <div *ngFor="let item of array">{{item}}</div>
    </div>
</ng-container>

答案 2 :(得分:0)

在 NgRx 10 及更高版本中,您可以将 *ngrxLet 指令与 @ngrx/component 包 (documentation) 一起使用。

用法示例:

<ng-container *ngrxLet="observableNumber$ as n">
    <app-number [number]="n">
    </app-number>
</ng-container>