2

我尝试使用 Hasura 的 GraphQL 后端在 Angular 7 项目上实现无限虚拟滚动。

我无法弄清楚为什么没有添加新数据以及滚动时为什么会有多个 API 请求。

这是组件,feed.component.ts

import { Component, OnInit, ViewChild } from '@angular/core';
import { IdeaService } from '@app/core/idea/idea.service';
import { MatDialog } from '@angular/material';
import { IdeaCardComponent } from '@app/shared/idea-card/idea-card.component';
import { CdkVirtualScrollViewport } from '@angular/cdk/scrolling';
import { Observable, BehaviorSubject } from 'rxjs';
import { map, tap, merge, throttleTime, scan, mergeMap } from 'rxjs/operators';

const batchSize = 10;

@Component({
  selector: 'app-idea-feed',
  templateUrl: './idea-feed.component.html',
  styleUrls: ['./idea-feed.component.scss']
})
export class IdeaFeedComponent implements OnInit {
  @ViewChild(CdkVirtualScrollViewport)
  viewport: CdkVirtualScrollViewport;

  isEndOfTheList = false;
  offset = new BehaviorSubject(null);
  infinite: Observable<any[]>;

  length: number;
  ideaList: any[] = [];
  pageIndex = 0;
  pageEvent: any;
  constructor(private ideaService: IdeaService, public dialog: MatDialog) {
    const batchMap = this.offset.pipe(
      throttleTime(500),
      mergeMap(n => this.getIdeasFromServer(n)),
      scan((acc, batch) => {
        return { ...acc, ...batch };
      }, {})
    );

    this.infinite = batchMap.pipe(map(v => Object.values(v)));
    console.log(this.infinite);
  }

  nextBatch(e: any, offset: any) {
    if (this.isEndOfTheList) {
      return;
    }

    const end = this.viewport.getRenderedRange().end;
    const total = this.viewport.getDataLength();

    if (end === total) {
      this.offset.next(offset);
    }
  }

  trackByIndex(i: any) {
    return i;
  }


  ngOnInit() {
    this.ideaService.getTotalIdeaCount().subscribe(data => {
      this.length = data.data.ideas_aggregate.aggregate.count;
    });
  }

  getIdeasFromServer(pageIndex: any) {
    console.log(this.ideaList, this.pageIndex);

    return this.ideaService.getNIdeas(batchSize, pageIndex).pipe(
      map((data: any) => {
        this.pageIndex += 10;
        data.data.ideas.forEach((idea: any) => {
          this.ideaList.push(idea);
        });
        this.ideaList = data.data.ideas;
        return data.data.ideas;
      })
    );
  }
}

这是 HTML,feed.component.html

<div *ngIf="(infinite | async) as ideaList" class="ideafeed-background">
  <cdk-virtual-scroll-viewport itemSize="100" scrolledIndexChange)="nextBatch($event, pageIndex)">
        <mat-card
          class="idea-card"
          *cdkVirtualFor="let item of ideaList; let i = index; trackBy: trackByIdx">
     {{ item.name }}
    </mat-card>
  </cdk-virtual-scroll-viewport>
</div>

我不确定我做错了什么。我已经按照这个教程

4

1 回答 1

1

我有同样的问题。我改变了push方法:

this.ideaList = [...this.ideaList, idea];
于 2019-04-09T15:08:31.133 回答