web-dev-qa-db-ja.com

Angular仮想スクロール付きの材料CDKツリーコンポーネント

Angular MaterialのCDKツリーコンポーネントのドキュメントにはこう書かれています:

"フラットツリーは、スタイルと検査が一般的に簡単です。また、無限または仮想スクロール"

CDKフラットツリーに仮想スクロールを適用する方法はありますか?

レンダリングする大規模なツリーがありますが、現在は非常に遅く、すべてのノードを再帰的に開くとクラッシュします

<cdk-virtual-scroll-viewport> @ angular/cdk-experimentalを試しましたが、ツリーコンポーネントと統合する方法がわかりませんでした

11
Ragnar

仮想ビューポートの主な機能は、スクロールイベントを追跡し、現在画面上にある要素を通知することです。この情報を使用して、ツリーのデータソースを変更して、画面上にあるノードのみにすることができます。

問題は、現在のところ、ビューポートが実際に機能するのは、高さが一定のアイテムでのみであるということです。ツリーのノードを展開すると、そのノードの高さは他の閉じたノードと一致しません。これを回避するために、ノードが展開されているときはいつでも、子ノードを仮想ビューポートのデータソースに追加できる場合があります。

とりあえず、拡張ノードの問題は無視します。

ツリーで基本的な仮想スクロールを取得するには、これをテンプレートに追加します。

<cdk-virtual-scroll-viewport itemSize="48" style="height: 200px;">
  <ng-container *cdkVirtualFor="let item of fullDatasource"></ng-container>

  <mat-tree [dataSource]="dataSource" [treeControl]="treeControl">...</mat-tree-node>
  </mat-tree>
</cdk-virtual-scroll-viewport>

各ノードのサイズを伝えて、ビューポートを作成します。次に、virtualForOfを追加し、fullDatasourceを渡して、ビューポートの高さがわかるようにします。 virtualForOfの使用目的はテンプレートにスクロールするアイテムが含まれているが、空のままにしておくことでうまくいくように思えるので、これは少しごまかしているかもしれません。

残っていることは、ツリーのデータソースが完全なデータソースの可視アイテムのみであることを確認することです。最初にコンストラクタで宣言する方法を変更しますが、これはよりエキサイティングな部分です。

  ngAfterViewInit() {
    this.virtualScroll.renderedRangeStream.subscribe(range => {
      console.log(range, 'range')
      this.dataSource.data = this.fullDatasource.slice(range.start, range.end)
    })
  }

スクロールが変わるたびに範囲を出力するrenderedRangeStreamをサブスクライブします。それが発生するときはいつでも、データソースを適切なスライスに設定するだけです!

Stackblitzと結果 うまくいけば、これで開始できます!

2
Benjamin Kindle
  • npm install @angular/[email protected]またはng add @angular/[email protected]
  • Scrolling Moduleをアプリケーションにインポートするapp.module.ts
    • import { ScrollingModule } from '@angular/cdk/scrolling';
    • @ngmodule内のインポートにScrollingModuleを追加
  • hTMLファイル内にcdk-virtual-scroll-viewportを追加します
<cdk-virtual-scroll-viewport  style="height: 250px" itemSize="50" >
//your code will be here
    
</cdk-virtual-scroll-viewport>
0