Как реализовать виртуальную прокрутку на уровне grand child дерева материалов

У меня есть угловое дерево-мат с родительским, дочерним и великим дочерним уровнями. При нажатии на ребенка я добавляю в него внука. Но у внука огромные данные до 4к записей. Что делает дерево очень медленным. Мой код, как показано ниже

<div *ngIf="isGrandChildLoaded"><mat-spinner></mat-spinner></div>
<mat-tree [dataSource]="dataSource" [treeControl]="treeControl">
  <!-- This is the tree node template for leaf nodes -->
  <mat-tree-node *matTreeNodeDef="let node" matTreeNodePadding>
    <!-- use a disabled button to provide padding for tree leaf -->
    <button mat-icon-button disabled></button>
    {{node.name}}
  </mat-tree-node>
  <!-- This is the tree node template for expandable nodes -->
  <mat-tree-node *matTreeNodeDef="let node;when: hasChild" matTreeNodePadding>
    <button mat-icon-button matTreeNodeToggle
            [attr.aria-label]="'toggle ' + node.name">
      <mat-icon class="mat-icon-rtl-mirror" (click)="clickTreeNode(node)">
        {{treeControl.isExpanded(node) ? 'expand_more' : 'chevron_right'}}
      </mat-icon>
    </button>
    {{node.name}}
  </mat-tree-node>
</mat-tree>

Обратите внимание на то, что я пробовал в stackblitz: My код

Я заметил, что виртуальная прокрутка будет лучшим решением в этом случае. И я видел пример: Ссылка

Но в примере это virtual-scroll на уровне всего дерева с полным источником данных.

Как можно добавить виртуальный свиток на уровне внука с 10 элементами за раз. Так что DOM и Tree не замораживаются. Пожалуйста, направьте меня ...


person androidGenX    schedule 09.05.2019    source источник


Ответы (1)


Чтобы виртуализировать дерево, сопоставьте иерархические данные с плоским списком, чтобы каждый элемент включал исходные данные плюс информацию об иерархии.

Эти данные, например,

    [{ 
        name: 'item 1', 
        children: [{ 
            name: 'sub item 1', 
            children: [{ 
                name: 'grandchild 1', 
                children: [] 
            }]
        }]
    }]

Станет

    [
        { name: 'item 1', depth: 0, parent: null },
        { name: 'sub item 1', depth: 1, parent: /*ref to 'item 1'*/ },
        { name: 'grandchild 1', depth: 2, parent: /*ref to 'sub item 1'*/ }
    ]

Когда данные сведены, их можно виртуализировать так же, как и любой плоский список. Используйте глубину для отступа элементов и используйте parent для переключения включения дочернего элемента в список на основе родительского состояния раскрытия.

Кроме того, вот реализация на основе angular, которую я только что опубликовал. https://github.com/gjcampbell/ooffice/tree/master/projects/of-tree

person sledgebox    schedule 04.01.2020