角度虚拟滚动:在到达滚动结束时附加新项目

问题描述 投票:4回答:1

我想在我的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中所述。

angular scrollbar infinite-scroll virtualscroll angular-cdk-virtual-scroll
1个回答
8
投票

在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/你可能在那里可以学到更多东西。

© www.soinside.com 2019 - 2024. All rights reserved.