web-dev-qa-db-fra.com

Angular scroll virtuel: ajoutez de nouveaux éléments lorsque vous atteignez la fin du scroll

Je voudrais utiliser le défilement virtuel sur mon Angular. Les éléments de ma liste sont le résultat d'une recherche paginée à distance. Je voudrais charger plus de résultats (appeler la page suivante) à chaque fois J'atteins la fin de la fenêtre en faisant défiler vers le bas.

Voici mon modèle:

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

Voici mes tentatives pour le faire fonctionner comme j'ai besoin:

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);
        });
    }
}

Comme vous pouvez le voir, je ne peux pas comprendre comment déclencher l'appel à ma fonction nextSearchPage (pour charger plus de résultats) uniquement lorsque la barre de défilement atteint la fin des éléments rendus dans la liste.

Savez-vous comment je peux faire ça?

La documentation du défilement angulaire est pauvre et il manque d'exemples, comme indiqué dans ce problème également.

12
smartmouse

La façon la plus simple de résoudre ce problème est d'utiliser le scrolledIndexChange.

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

$ event est le premier index des éléments rendus pour le moment. Par conséquent, vous pouvez appeler la page suivante lorsque l'index du premier élément est proche de la fin des éléments de la liste

N'oubliez pas que les éléments ont une hauteur fixe (itemSize), il est donc facile d'identifier la quantité d'éléments qui sont rendus à la fois.

par exemple.

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