通过CDK自动调整大小虚拟scoll策略保持滚动位置

问题描述

使用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 = [];
  }

stackblitz example

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...