Как раскрыть всю ветку дерева в mat-tree?

В Angular и библиотеке Angular Material есть компонент mat-tree, который представляет собой дерево, состоящее из вложенных узлов. Часто возникает необходимость раскрыть всю ветку дерева, то есть отобразить все дочерние узлы на определенном уровне иерархии.

Сначала нужно добавить к каждому узлу свойство, которое будет указывать на его статус: раскрыт узел или нет. Возможные значения этого свойства могут быть true (учитывая, что ветка раскрыта) и false (если ветка скрыта). Для этого можно добавить новое свойство "expanded" к каждому узлу в вашем массиве данных, который используется для создания дерева. Например:

nodes = [
  {
    name: 'Node 1',
    children: [
      {
        name: 'Child 1',
        children: [
          {
            name: 'Grandchild 1'
          },
          {
            name: 'Grandchild 2'
          }
        ]
      },
      {
        name: 'Child 2'
      }
    ],
    expanded: true // указываем, что ветка раскрыта
  },
  {
    name: 'Node 2',
    children: [
      {
        name: 'Child 3'
      },
      {
        name: 'Child 4'
      }
    ]
  }
];

Затем в шаблоне компонента mat-tree можно использовать директиву ngFor, чтобы рекурсивно отобразить все узлы дерева:

<mat-tree [dataSource]="dataSource" [treeControl]="treeControl">
  <mat-tree-node *matTreeNodeDef="let node; when: hasChild">
    <button mat-icon-button [matTreeNodeToggle]="node">
      <mat-icon>{{treeControl.isExpanded(node) ? 'expand_more' : 'chevron_right'}}</mat-icon>
    </button>
    {{node.name}}
    <mat-progress-bar *ngIf="isLoading(node)" mode="indeterminate"></mat-progress-bar>
  </mat-tree-node>

  <mat-tree-node *matTreeNodeDef="let node; when: isFile">
    <button mat-icon-button disabled></button>
    {{node.name}}
  </mat-tree-node>
</mat-tree>

Компонент mat-tree-node отвечает за отображение каждого узла дерева. Внутри него мы используем кнопку с иконкой, чтобы раскрывать или скрывать детей узла. Мы также отображаем имя узла с помощью двойных фигурных скобок.

Для управления состоянием раскрытия узлов, вам понадобятся классы TreeControl и NestedTreeControl из библиотеки Angular Material. Вы можете импортировать их и использовать в компоненте:

import {Component} from '@angular/core';
import {MatTreeNestedDataSource} from '@angular/material/tree';
import {NestedTreeControl} from '@angular/cdk/tree';

@Component({
  selector: 'app-tree',
  templateUrl: 'tree.component.html',
  styleUrls: ['tree.component.css'],
})
export class TreeComponent {
  treeControl = new NestedTreeControl<Node>(node => node.children);
  dataSource = new MatTreeNestedDataSource<Node>();

  constructor() {
    this.dataSource.data = this.nodes;
  }

  hasChild = (_: number, node: Node) => !!node.children && node.children.length > 0;

  /* далее идут другие методы и свойства компонента */
}

Здесь мы создаем экземпляры TreeControl и MatTreeNestedDataSource, которые связываются с компонентом mat-tree в шаблоне. В конструкторе мы присваиваем данные массива nodes к dataSource.

Теперь мы можем добавить методы для управления состоянием раскрытия узлов. Например, допустим, что у нас есть кнопка, которую пользователь может нажать, чтобы раскрыть все ветки дерева:

expandAll() {
  this.treeControl.expandAll();
}
<button mat-raised-button (click)="expandAll()">Раскрыть все</button>

Метод expandAll() вызывает метод expand() каждого узла в дереве, чтобы раскрыть их все. Когда пользователь нажимает на кнопку, вызывается метод expandAll() и все ветки дерева открываются.

Вот, в общем, подробное объяснение о том, как раскрыть всю ветку дерева в компоненте mat-tree в Angular.