Основная функция виртуального видового экрана - отслеживать события прокрутки и уведомлять вас, какие элементы в данный момент находятся на экране.Используя эту информацию, вы можете изменить источник данных дерева, чтобы он отображал только те узлы, которые находятся на экране.
Проблема в том, что сейчас область просмотра действительно хорошо работает только с элементами одинаковой высоты.Когда вы раскрываете узел дерева, этот узел имеет высоту, которая не соответствует остальным закрытым.Чтобы обойти это, вы можете добавлять дочерние узлы в источник данных виртуального окна просмотра всякий раз, когда узел расширяется.
На данный момент я буду игнорировать проблему расширенного узла.
Чтобы получитьОбычная виртуальная прокрутка с деревом, добавьте это в свой шаблон:
<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 с результатом Надеюсь, этого достаточно, чтобы вы начали!