/
githubmirror
/
components
Обзор
Документация
Войти
/
githubmirror
/
components
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/components-examples/material/tree/tree-dynamic/tree-dynamic-example.ts
96 строк
3 KB
Kristiyan Kostadinov
docs(material/tree): dynamic example not updating (#33365)
08 июн 2026, 10:56
Не верифицирован
08 июн 2026, 10:56
0262a4f
Код
Авторство
О чём код?
import {Component, Service, WritableSignal, inject, signal} from '@angular/core'; import {MatProgressBarModule} from '@angular/material/progress-bar'; import {MatIconModule} from '@angular/material/icon'; import {MatButtonModule} from '@angular/material/button'; import {MatTreeModule} from '@angular/material/tree'; /** Node with expandable and level information */ interface DynamicNode { name: string; level: number; expandable: boolean; isLoading: WritableSignal<boolean>; children?: DynamicNode[]; } /** * Database for dynamic data. When expanding a node in the tree, the data source will need to fetch * the descendants data from the database. */ @Service() export class DynamicDatabase { dataMap = new Map<string, string[]>([ ['Fruits', ['Apple', 'Orange', 'Banana']], ['Vegetables', ['Tomato', 'Potato', 'Onion']], ['Apple', ['Fuji', 'Macintosh']], ['Onion', ['Yellow', 'White', 'Purple']], ]); rootLevelNodes: string[] = ['Fruits', 'Vegetables']; /** Initial data from database */ initialData(): DynamicNode[] { return this.rootLevelNodes.map(name => this.createNode(name, 0, true)); } createNode(name: string, level: number, expandable: boolean): DynamicNode { return { name, level, expandable, isLoading: signal(false), children: undefined, }; } getChildren(name: string): string[] | undefined { return this.dataMap.get(name); } isExpandable(name: string): boolean { return this.dataMap.has(name); } } /** * @title Tree with dynamic data */ @Component({ selector: 'tree-dynamic-example', templateUrl: 'tree-dynamic-example.html', styleUrl: 'tree-dynamic-example.css', imports: [MatTreeModule, MatButtonModule, MatIconModule, MatProgressBarModule], }) export class TreeDynamicExample { private _database = inject(DynamicDatabase); readonly dataSource = signal(this._database.initialData()); readonly childrenAccessor = (node: DynamicNode) => node.children ?? []; readonly hasChild = (_: number, node: DynamicNode) => node.expandable; /** * Load children on node expansion. * Called from template via (expandedChange) output. */ onNodeExpanded(node: DynamicNode, expanded: boolean): void { if (!expanded || node.children) { // Don't reload if collapsing or already loaded return; } const childNames = this._database.getChildren(node.name); if (!childNames) { return; } node.isLoading.set(true); // Simulate async data loading setTimeout(() => { node.children = childNames.map(name => this._database.createNode(name, node.level + 1, this._database.isExpandable(name)), ); node.isLoading.set(false); this.dataSource.set([...this.dataSource()]); }, 1000); } }