角度虚拟滚动:到达滚动末尾时追加新项目 [英] Angular virtual scroll: append new items when reaching the end of scroll

查看:166
本文介绍了角度虚拟滚动:到达滚动末尾时追加新项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在Angular应用程序上使用虚拟滚动.我列表中的项目是远程页面搜索的结果.每当我向下滚动到视口结束时,我想加载更多结果(调用下一页).

I would like to use virtual scroll on my Angular application. The items in my list are the result of a remote paged search. I would like to load more results (call the next page) every time I reach the end of the viewport scrolling down.

这是我的模板:

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

这是我尝试使其按需运行:

Here is my attempts to make it to work as I need:

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 函数的调用(以加载更多结果)

As you can see I can't figure out how to trigger the call to my nextSearchPage function (to load more results) only when the scrollbar reaches the end of the current rendered items in the list.

你知道我该怎么做吗?

如本 issue 所述,角度滚动文档很差且缺少示例.也是

Angular scrolling documentation is poor and it lacks of examples, as stated in this issue as well.

推荐答案

在CdkScrollable上有一个measureMeasureOffOffset函数可能会有所帮助.您可以订阅滚动事件并检查偏移量以确定滚动位置.

There is a function measureScrollOffset on CdkScrollable that may help. you can subscribe to scroll events and check the offset to determine where you have scrolled.

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

并且您需要在滚动项目集合更改后手动调用detectChange.尽管我没有找到解决方法,但是这里有一个问题:更改检测到后,滚动条将返回到开始位置.

And you need to manually call detectChange after scroll item collection change. There's one problem though I have not find a solution: the scroll bar will return to beginning after change detection.

在此处查看演示: https://stackblitz.com/edit/template-angular7-material-primeng-ckxgzs

结果证明,侦听滚动结束可能不是一个好主意.更好的方法是监听渲染范围(我相信这是DOM中渲染的实际项目)的变化.一旦渲染范围结束等于数据长度,就可以将更多数据添加到集合中了.这样就解决了酒吧重新开始的问题.

Turns out listening for end of scroll is probably not a good idea. A better one is listening for rendering range(I believe it's the actual items rendered in the DOM) change. Once the rendering range ends equals data length, that's the time to add more data to the collection. And this somehow solves the problem of bar going back to beginning.

 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/您可能在那里可以了解更多信息.

To be honest, I got the idea from: https://angularfirebase.com/lessons/infinite-virtual-scroll-angular-cdk/ You probably can learn more there.

这篇关于角度虚拟滚动:到达滚动末尾时追加新项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆