在AsyncPipe
内使用*ngIf
时,如果连接到Observable
的{{1}}在AsyncPipe
变为真之前推送其值,则该值从*ngIf
返回的信息将不正确。
例如,假设我有:
AsyncPipe
然后说事件按此顺序发生:
<div *ngIf="showPipe">
<div *ngFor="let item of arrObs | async">{{item}}</div>
</div>
是错误的showPipe
推动[1,2,3] arrObs
设置为true 从我所见,showPipe
的行为就像*ngFor
返回null一样。
解决此问题的一种方法是改用arrObs | async
,但是[hidden]
有很多好处,例如性能和使null处理更容易。
执行此操作的正确方法是什么?我是否应该完全不使用可观察对象来显示内容?我以为使用可观察的方法是最Angular-y的工作方式。
编辑:
我可观察到的实际上只是一个*ngIf
,我称之为new Subject()
。
答案 0 :(得分:3)
有一些方法可以解决此问题。我建议在您的shareReplay
上添加一个Observable
运算符:
readonly arrObs = this.someDataFromSomewhere().pipe(
shareReplay(1)
);
如果您的Observable
实际上是Subject
,您也可以将其更改为BehaviorSubject
或ReplaySubject
这样,您将始终获得有关订阅的最新数据。
还有一些方法可以在模板中处理并保持*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>