如何在Angular中的异步管道中合并数据

时间:2018-10-29 11:16:04

标签: javascript angular rxjs

我已经在Angular 6中通过使用异步管道显示了youtube视频。在第一次加载时效果很好。

这是使用方式。

组件HTML文件:

<div id="youtube" class="search-results" *ngIf="(trendingVideos | async) as videos; else loadingOrError"></div>

组件TS文件:

public trendingVideos: Observable<VideoClass[]>;
private loadVideos(videosPerPage?: number, regionCode?: string, videoCategoryId?: number) {
      this.trendingVideos = this.youtubeService.getTrendingVideos(videosPerPage, regionCode, videoCategoryId, false)
        .pipe(
          catchError((error: any) => {
            this.loadingError$.next(true);
            return throwError(error);
          })
        );
  }

捕获错误也可以正常工作。

服务文件:

public getTrendingVideos(videosPerPage?: number, regionCode?: string, videoCategoryId?: number, paginationMode?: boolean): Observable<VideoClass[]> {
    const params: any = {
      part: appConfig.partsToLoad,
      chart: appConfig.chart,
      videoCategoryId: videoCategoryId ? videoCategoryId : appConfig.defaultCategoryId,
      regionCode: regionCode ? regionCode : appConfig.defaultRegion,
      maxResults: videosPerPage ? videosPerPage : appConfig.maxVideosToLoad,
      key: appConfig.youtubeApiKey
    };
    return this.http.get<any>(appConfig.getYoutubeEndPoint('videos'), { params })
      .pipe(
        map(
          (data) => {
            return data.items
              .map((item) => new VideoClass(item))
              .filter((item) => item.id !== '');
          }
        ),
        catchError(this.handleError('getTrendingVideos'))
      ) as Observable<VideoClass[]>;
  }

第一次加载数据时工作正常。现在我正在开发无限滚动。因此,我再次调用此API。但是想将数据合并到以前加载的数据中。

当我的无限滚动插件调用它时,它每次都用新数据替换数据。

这是无限滚动功能:

private onScroll(){
    let videosData:Observable<VideoClass[]> = this.youtubeService.getTrendingVideos(this.videoCount, this.regionCode, this.categoryID, true)
    .pipe(
      catchError((error: any) => {
        this.loadingError$.next(true);
        return throwError(error);
      })
    );
    // Here how i merge this same video data to previously loaded trending videos data.
  }

有帮助吗?

2 个答案:

答案 0 :(得分:0)

您只需要使用rxjs映射运算符并在其中返回一个新数组,就您的情况而言就是这样:

编辑:

使用行为主题来通过api调用获取新的视频。

这是一个实时示例:Stackblitz

component.ts

private videos = [];
private newVideos$ = new BehaviorSubject<VideoClass[]>([]);
public trendingVideos: Observable<VideoClass[]>;

ngOnInit(){
   this.trendingVideos = this.newVideos$.pipe(
     filter(data => data.length > 0),
     map(data => {
        this.videos = [...this.videos, ...data];
        return this.videos;
     });
}
private loadVideos(videosPerPage?: number, regionCode?: string, videoCategoryId?: number) {
  this.youtubeService.getTrendingVideos(videosPerPage, regionCode, videoCategoryId, false)
    .pipe(
      catchError((error: any) => {
        this.loadingError$.next(true);
        return throwError(error);
      })
    ).subscribe(newVideos => this.newVideos$.next(newVideos));
}

希望有帮助!

答案 1 :(得分:0)

将“无限滚动”修改为:

private onScroll(bufferObj$) {
    return zip(bufferObj$, this.youtubeService.getTrendingVideos(this.videoCount, this.regionCode, this.categoryID, true)
    .pipe(
        catchError((error: any) => {
            this.loadingError$.next(true);
            return throwError(error);
        })
    )).pipe(map((x: any) => x[0].concat(x[1])));
}