使用 CDK autosize 虚拟滚动策略维护滚动位置
Maintain scroll position with CDK autosize virtual scroll strategy
使用 CDK 自动调整虚拟滚动策略保持滚动位置
我有一大堆可以使用 @angular/cdk-experimental
提供的 <cdk-virtual-scroll-viewport autosize>
滚动的项目列表(这些项目具有动态高度,因此我使用这种滚动策略而不是 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 = [];
}
使用 CDK 自动调整虚拟滚动策略保持滚动位置
我有一大堆可以使用 @angular/cdk-experimental
提供的 <cdk-virtual-scroll-viewport autosize>
滚动的项目列表(这些项目具有动态高度,因此我使用这种滚动策略而不是 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 = [];
}