簡體   English   中英

rxjs:在已經使用異步管道顯示第一個的同時組合 observables 的結果

[英]rxjs: Combine result of observables while already displaying the first with async pipe

使用 rxjs 在 angular 中已經顯示第一個 observable 的結果並在其他 observable 完成時組合數據的最佳方式是什么?

例子:

@Component({
    selector: 'app-component',
    template: `
<div *ngFor="let group of groups$ | async">
    <div *ngFor="let thisItem of group.theseItems">
        ...
    </div>
    <div *ngFor="let thatItem of group.thoseItems">
        ...
    </div>
</div>
`
})
export class AppComponent implements OnInit {
    ...
    ngOnInit() {
        this.groups$ = this.http.get<IThisItem[]>('api/theseItems').pipe(
            map(theseItems => {
                return theseItems.groupBy('groupCode');
            })
        );

        // combine these results? This operation can take 5 seconds
        this.groups$$ = this.http.get<IThatItem[]>('api/thoseItems').pipe(
            map(thoseItems => {
                return thoseItems.groupBy('groupCode');
            })
        );
    }
}

我知道這可以通過訂閱兩者來完成,並合並結果。 但是是否可以為此使用管道運算符並使用async管道?

我認為您可以使用combineLatest rxjs 運算符。 這可能意味着您也稍微更改了模板中的處理方式。

我不能使用你的例子,因為我不知道你的 get 函數,但基本上適用相同的原則。

在此處查看 stackblitz以獲取示例:

export class AppComponent  {

  private firstObservable = of([{name: 'name1'}]).pipe(startWith([]));
  private secondObservable = of([{name: 'name2'}]).pipe(startWith([]));

  combined = combineLatest(this.firstObservable, this.secondObservable).pipe(
        map(([firstResult, secondResult]) => {
          return [].concat(firstResult).concat(secondResult)
        }) 
   );
}

html輸出:

<span *ngFor="let item of combined | async">{{item.name}}<span>

您可以使用合並和掃描。

  first$: Observable<Post[]> = this.http.get<Post[]>('https://jsonplaceholder.typicode.com/posts?userId=1');
  second$: Observable<Post[]>  = this.http.get<Post[]>('https://jsonplaceholder.typicode.com/posts?userId=2');
  combinedPosts$: Observable<Post[]> = merge(this.first$, this.second$).pipe(
    scan((acc: Post[], curr: Post[]) => [...acc, ...curr], [])
  )

https://www.learnrxjs.io/operators/combination/merge.html從多個中觀察一個。

https://www.learnrxjs.io/operators/transformation/scan.html掃描類似於array.reduce...你可以累積每個可觀察發射的結果。

工作示例: https : //stackblitz.com/edit/angular-lrwwxw

combineLatest運算符不太理想,因為它要求每個 observable 在組合的 observable 可以發出之前發出: https : combineLatest

請注意,在每個 observable 至少發出一個值之前, combineLatest 不會發出初始值。

異步管道只是 observable 的訂閱者...要回答您的問題,您可以使用任何可能的方式...例如:

<div *ngFor="let group of groups$ | async as groups">
    <div *ngFor="let thisItem of group.theseItems">
        ...
    </div>
</div>

public groups$: Observable<type> = this.http.get<IThatItem[]>.pipe(
  startWith(INITIAL_VALUE)
);

或者

public groups$: Observable<type> = combineLatest(
  of(INITIAL_VALUE),
  this.http.get<IThatItem[]>
)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM