问题描述
使用CDK自动调整大小的虚拟scoll策略保持滚动位置
我有一大堆可以使用<cdk-virtual-scroll-viewport autosize>
提供的@angular/cdk-experimental
进行滚动的项目(这些项目具有动态高度,因此我使用的是滚动策略,而不是FixedSizevirtualscrollStrategy
)。
随着时间的流逝,新项目会插入到列表中,即它们会附加在顶部。当用户向下滚动时,我要避免新的项目将视口中的项目推开。因此,我需要一种机制来在添加项目后维护/恢复滚动位置。
我有一个半有效的解决方案(并且很棘手,因为它读取私有字段),但是在添加项目之后,视口会随机移动几个像素。
以下是相关的代码部分:
@ViewChild(CdkvirtualscrollViewport) viewport: CdkvirtualscrollViewport;
...
// After new items have been added:
const offset = this.viewport.measureScrollOffset('top');
const topPosition = offset + newItems.length * this.viewport['_scrollStrategy']._averager._averageItemSize; // the autosize strategy determines an average item size I'm trying to use to determine how the viewport should be shifted
this.viewport.scrollTo({
top: topPosition
});
我在此处创建了这种方法的演示:https://stackblitz.com/edit/angular-be926g?file=src/app/cdk-virtual-scroll-overview-example.ts
有什么想法如何在恒定视口中无缝实现这一目标吗?
解决方法
您可以使用this.viewport.getRenderedRange()
检查视口在顶部,如果为零,则附加元素,否则将其保留在存储桶中,并在用户滚动到视口顶部时附加对象。
const range = this.viewport.getRenderedRange();
console.log("range",range);
bucket = [...bucket,...newItems];
console.log("bucket",bucket);
if (range.start == 0) {
this.items = [...bucket.reverse(),...this.items];
bucket = [];
}