简体   繁体   中英

Infinite loop when using *ngFor with async pipe in Angular

My problem is very similar to this one .

In foo.component.html :

<ng-container *ngFor="let item of items">
    <ng-container *ngIf="(fooFunc(item.property) | async) as element">
        {{ element | json }}
    </ng-container>
</ng-container>

In foo.component.ts :

fooFunc(foo: any) {
  return this.fooService.fooServiceFunc(foo).pipe(
    take(1),
    shareReplay(1)
  );
}

The fooServiceFunc in fooService will return only one Observable at one time.

My problem is that now my app fires infinite requests (after the whole items array has been iterated, it will fire the request again from beginning, over and over), which seems to be a side-effect of async pipe which is announced in this answer . But I still cannot figure out how to fix this?

Save you shared stream to variable and use the variable in template

data$ = forkJoin(
  this.items.map(item => this.fooService.fooServiceFunc(item.property).pipe(
    map(fetchResult => ({ fetchResult, item })
  ))
)
<ng-container *ngFor="let item of data$ | async">
    <ng-container *ngIf="item.fetchResults">
        {{ item.fetchResults | json }}
    </ng-container>
</ng-container>

Now you create new stream for each item , and each query runs change detection, whitch runs queries again.

My advice: Try to avoid function calls in templates, functions in template executes when changeDetection for current component runs (AsyncPipe run change detection by each value in the input stream).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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