ngIf指令中的异步管道

When using the AsyncPipe inside of an *ngIf, if the Observable connected to the AsyncPipe pushes its values before the *ngIf becomes true, the value returned from the AsyncPipe will be incorrect.

例如,假设我有:

<div *ngIf="showPipe">
    <div *ngFor="let item of arrObs | async">{{item}}</div>
</div>

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

  1. showPipe is false
  2. arrObs pushes [1,2,3]
  3. showPipe is set to true

From what I've seen, the *ngFor will act as if arrObs | async returned null.

One solution to this problem is to use [hidden] instead, but there are a lot of benefits to *ngIf, like performance and making null handling easier.

正确的方法是什么?我是否应该根本不使用可观察对象来显示内容?我以为使用可观察的是最角度的工作方式。

评论
sit_in
sit_in

Surround your structure in an ng-container which contains the async pipe and stores the value in a variable using as. Also use the ng-if directive to load the container only after you get a value in that async pipe.

<ng-container *ngIf="( arrObs| async ) as array">
    <div *ngIf="showPipe">
        <div *ngFor="let item of array">{{item}}</div>
    </div>
</ng-container>
点赞
评论
无言以对
无言以对

There are some ways you can solve this. I would suggest adding a shareReplay operator on your Observable:

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

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

There are also ways to handle this in the template and still maintain the *ngIf benefits:

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

Or if you don't want the *ngIf to wait for the observable

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