簡體   English   中英

帶虛擬滾動的角度材質 CDK 樹組件

[英]Angular material CDK tree component with virtual scroll

Angular Material CDK 樹組件文檔說:

“扁平樹通常更容易設計和檢查。它們對滾動變化也更友好,例如無限或虛擬滾動

任何想法如何將虛擬滾動應用於 CDK 平面樹?

我有一棵巨大的樹要渲染,現在它很慢,當我遞歸地打開所有節點時,它會崩潰

我嘗試了 < cdk-virtual-scroll-viewport > @angular/cdk-experimental 但沒有弄清楚如何將它與樹組件集成

我知道這很舊,但是我在試圖找出完全相同的東西時遇到了這個線程,經過多次實驗,我已經找到了一個虛擬滾動扁平樹的基本工作示例,如果您已經需要進行非常小的修改有一個可用的 cdk 樹

我的解決方案的關鍵是放棄 cdk-tree 指令並直接將我的 MatTreeFlatDataSource 和 FlatTreeControl 與 *cdkVirtualFor 一起使用。 您可能已經將這些對象設置為作為輸入傳遞到 cdk-tree。 cdk-tree 實際上只是圍繞這兩個承擔所有繁重工作的對象的輕量級包裝。

這是一個stackblitz,一個更具體的例子: https ://stackblitz.com/edit/angular-b5nkkd?file=src/app/app.component.html

這是它包含的內容:

  • 兩個滾動的扁平樹從相同的底層數據源繪制並由相同的底層樹控件控制(即,它們保存相同的數據,您對一棵樹所做的任何事情也將反映在另一棵樹中)

  • 第一棵樹使用 cdk-tree 指令,但我不知道如何讓它與 CDK 虛擬滾動一起工作,因此它呈現所有節點

  • 第二棵樹不使用 cdk-tree,但我能夠讓虛擬滾動干凈利落地工作,只需很少的更改。 因此,您必須自己做樣式和一些基本邏輯,但是如果您查看 stackblitz 中模板代碼的差異,您會發現它並沒有那么糟糕。

  • 我正在顯示每個滾動容器正在渲染的節點數,以證明虛擬滾動在一個而不是另一個中工作

虛擬視口的主要功能是跟蹤滾動事件並通知您當前屏幕上的元素。 使用此信息,您可以將樹的數據源修改為僅顯示在屏幕上的節點。

現在的問題是,視口實際上只適用於高度一致的項目。 當您展開樹的一個節點時,該節點的高度與其余封閉節點的高度不一致。 為了解決這個問題,您可以在節點展開時將子節點添加到虛擬視口的數據源。

現在,我將忽略擴展節點問題。

要使用樹進行基本的虛擬滾動,請將其添加到您的模板中:

<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 結果希望這足以讓你開始!

  • npm install @angular/cdk@7.0.0ng add @angular/cdk@7.0.0
  • 將滾動模塊導入您的應用程序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>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM