7

CDK autosize 仮想スクロール戦略でスクロール位置を維持する

<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

一定のビューポートでこれをシームレスに達成する方法はありますか?

4

1 に答える 1

2

ビューポートが上にあることを確認し、ゼロの場合は要素を追加するために使用できます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 = [];
  }

スタックブリッツの例

于 2020-11-12T04:34:38.747 に答える