Угловая виртуальная прокрутка: добавление новых элементов при достижении конца прокрутки - PullRequest
0 голосов
/ 19 февраля 2019

Я хотел бы использовать виртуальную прокрутку в моем приложении 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 (чтобы загрузить больше результатов), только когда полоса прокрутки достигаетконец текущих отображаемых элементов в списке.

Знаете ли вы, как я могу это сделать?

Документация по угловой прокрутке плохая и в ней отсутствуют примеры, как указано в этой проблеме .

1 Ответ

0 голосов
/ 23 февраля 2019

В CdkScrollable есть функция measureScrollOffset, которая может помочь.Вы можете подписаться на события прокрутки и проверить смещение, чтобы определить, где вы прокручивали.

  ngAfterViewInit(): void {
    this.scrollDispatcher.scrolled().pipe(
      filter(event => this.virtualScroll.measureScrollOffset('bottom') === 0)
    ).subscribe(event => {
      this.searchPageNumber++;
      this.nextSearchPage(this.searchPageNumber); 
    })

И вам нужно вручную вызывать detectChange после изменения коллекции элементов прокрутки.Есть одна проблема, хотя я не нашел решения: полоса прокрутки вернется к началу после обнаружения изменений.

Проверьте демо здесь: https://stackblitz.com/edit/template-angular7-material-primeng-ckxgzs

Редактировать:

Оказывается, прослушивание конца прокрутки, вероятно, не очень хорошая идея.Лучше прислушиваться к диапазону рендеринга (я полагаю, что это фактические элементы, отображаемые в DOM).Когда диапазон рендеринга равен длине данных, самое время добавить дополнительные данные в коллекцию.И это как-то решает проблему возврата бара к началу.

 ngAfterViewInit(): void {
    this.scrollDispatcher.scrolled().pipe(
      filter(event => this.virtualScroll.getRenderedRange().end === this.virtualScroll.getDataLength())
    ).subscribe(event => {
      this.searchPageNumber++;
      this.nextSearchPage(this.searchPageNumber);
    })

Новое демо здесь: https://stackblitz.com/edit/template-angular7-material-primeng-fhikcf

Если честно, у меня возникла идея: https://angularfirebase.com/lessons/infinite-virtual-scroll-angular-cdk/ Вы, вероятно, можете узнать больше там.

...