web-dev-qa-db-ja.com

Angular仮想スクロール:スクロールの終わりに達したときに新しいアイテムを追加します

Angularアプリケーションで仮想スクロールを使用したい。私のリストの項目は、リモートページ検索の結果です。毎回より多くの結果(次のページを呼び出す)をロードしたいです。下にスクロールしてビューポートの最後に到達します。

これが私のテンプレートです:

<div class="container">
    <cdk-virtual-scroll-viewport itemSize="100">
        <li *cdkVirtualFor="let item of searchResult">{{item}}</li>
    </cdk-virtual-scroll-viewport>
</div>

これが、必要に応じて機能させるための私の試みです。

export class SearchComponent {
    @ViewChild(CdkVirtualScrollViewport) virtualScroll: CdkVirtualScrollViewport;
    searchPageNumber: number;
    searchResults: Array<any>;

    constructor(private scrollDispatcher: ScrollDispatcher, private searchService: SearchService) {
        this.searchPageNumber = 0;
        this.searchResults = [];
    }

    ngOnInit(): void {
        this.nextSearchPage(this.searchPageNumber);
    }

    ngAfterViewInit(): void {
        //this.scrollDispatcher.register(this.scrollable);
        //this.scrollDispatcher.scrolled(1000)
        //    .subscribe((viewport: CdkVirtualScrollViewport) => {
        //        console.log('scroll triggered', viewport);
        //    });

        this.virtualScroll.renderedRangeStream.subscribe(range => {
            console.log('range', range);
            console.log('range2', this.virtualScroll.getRenderedRange());
            if (this.virtualScroll.getRenderedRange().end % 10 === 0) {
                this.nextSearchPage(++this.searchPageNumber);
            }
        });
    }

    nextSearchPage(pageNumber: number): void {
        this.searchService.getResults(pageNumber).then((pagedResults) => {
            this.searchResults = this.searchResults.concat(pageResuls);
        });
    }
}

ご覧のとおり、スクロールバーがリスト内の現在レンダリングされているアイテムの最後に達した場合にのみ、nextSearchPage関数の呼び出しをトリガーする方法(結果をさらに読み込むため)を理解できません。

どうすればそれができるか知っていますか?

この issue で述べたように、角度スクロールのドキュメントは貧弱で、例が不足しています。

12
smartmouse

これを解決する最も簡単な方法はscrolledIndexChangeを使用することです。

<cdk-virtual-scroll-viewport itemSize="500" (scrolledIndexChange)="nextBatch($event)">

$ eventは、現時点でレンダリングされた要素の最初のインデックスです。したがって、最初の項目のインデックスがリスト内の項目の終わり近くにある場合、次のページを呼び出すことができます

アイテムの高さ(itemSize)は固定されているため、一度にレンダリングされる要素の量を簡単に識別できます。

例えば.

  nextBatch(index) {
    if (index + $itemsRenderAtTheMoment === this.items.length - 1) {
      this.page ++;
      this.loadMore();
    }
  }
1
mpenaloza