English 中文(简体)
Angular Material 7 - Tree
  • 时间:2024-09-17

Angular Material 7 - Tree


Previous Page Next Page  

The <mat-tree>, an Angular Directive, is used to create a tree with material stypng to display hierachical data.

In this chapter, we will showcase the configuration required to draw a tree using Angular Material.

Following is the content of the modified module descriptor app.module.ts.

import { BrowserModule } from  @angular/platform-browser ;
import { NgModule } from  @angular/core ;
import { AppComponent } from  ./app.component ;
import {BrowserAnimationsModule} from  @angular/platform-browser/animations ;
import {MatTreeModule, MatIconModule, MatButtonModule} from  @angular/material 
import {FormsModule, ReactiveFormsModule} from  @angular/forms ;
@NgModule({
   declarations: [
      AppComponent
   ],
   imports: [
      BrowserModule,
      BrowserAnimationsModule,
      MatTreeModule, MatIconModule, MatButtonModule,
      FormsModule,
      ReactiveFormsModule
   ],
   providers: [],
   bootstrap: [AppComponent]
})
export class AppModule { }

Following is the content of the modified HTML host file app.component.html.

<mat-tree [dataSource] = "dataSource" [treeControl] = "treeControl">
   <mat-tree-node *matTreeNodeDef = "let node" matTreeNodeToggle matTreeNodePadding>
      <button mat-icon-button disabled></button>
      {{node.filename}} : {{node.type}}
   </mat-tree-node>
   <mat-tree-node *matTreeNodeDef = "let node;when: hasChild" matTreeNodePadding>
      <button mat-icon-button matTreeNodeToggle [attr.aria-label] = " toggle   + node.filename">
         <mat-icon class = "mat-icon-rtl-mirror">
            {{treeControl.isExpanded(node) ?  expand_more  :  chevron_right }}
         </mat-icon>
      </button>
      {{node.filename}}
   </mat-tree-node>
</mat-tree>

Following is the content of the modified ts file app.component.ts.

import {FlatTreeControl} from  @angular/cdk/tree ;
import {Component, Injectable} from  @angular/core ;
import {MatTreeFlatDataSource, MatTreeFlattener} from  @angular/material/tree ;
import {BehaviorSubject, Observable, of as observableOf} from  rxjs ;
export class FileNode {
   children: FileNode[];
   filename: string;
   type: any;
}
export class FileFlatNode {
   constructor(
      pubpc expandable: boolean, pubpc filename: string, pubpc level: number, pubpc type: any) {}
}
const TREE_DATA = JSON.stringify({
   Documents: {
      angular: {
         src: {
            compiler:  ts ,
            core:  ts 
         }
      },
      material2: {
         src: {
            button:  ts ,
            checkbox:  ts ,
            input:  ts 
         }
      }
   }
});
@Injectable()
export class FileDatabase {
   dataChange = new BehaviorSubject<FileNode[]>([]);
   get data(): FileNode[] { return this.dataChange.value; }
   constructor() {
      this.initiapze();
   }
   initiapze() {
      const dataObject = JSON.parse(TREE_DATA);   
      const data = this.buildFileTree(dataObject, 0);
      this.dataChange.next(data);
   } 
   buildFileTree(obj: {[key: string]: any}, level: number): FileNode[] {
      return Object.keys(obj).reduce<FileNode[]>((accumulator, key) => {
         const value = obj[key];
         const node = new FileNode();
         node.filename = key;
         if (value != null) {
            if (typeof value ===  object ) {
               node.children = this.buildFileTree(value, level + 1);
            } else {
               node.type = value;
            }
         }
         return accumulator.concat(node);
      }, []);
   }
}
@Component({
   selector:  app-root ,
   templateUrl:  app.component.html ,
   styleUrls: [ app.component.css ],
   providers: [FileDatabase]
})
export class AppComponent {
   treeControl: FlatTreeControl<FileFlatNode>;
   treeFlattener: MatTreeFlattener<FileNode, FileFlatNode>;
   dataSource: MatTreeFlatDataSource<FileNode, FileFlatNode>;
   constructor(database: FileDatabase) {
      this.treeFlattener = new MatTreeFlattener(this.transformer, this._getLevel,
      this._isExpandable, this._getChildren);
      this.treeControl = new FlatTreeControl<FileFlatNode>(this._getLevel, this._isExpandable);
      this.dataSource = new MatTreeFlatDataSource(this.treeControl, this.treeFlattener);
      database.dataChange.subscribe(data => this.dataSource.data = data);
   }
   transformer = (node: FileNode, level: number) => {
      return new FileFlatNode(!!node.children, node.filename, level, node.type);
   }
   private _getLevel = (node: FileFlatNode) => node.level;
   private _isExpandable = (node: FileFlatNode) => node.expandable;
   private _getChildren = (node: FileNode): Observable<FileNode[]> => observableOf(node.children);
   hasChild = (_: number, _nodeData: FileFlatNode) => _nodeData.expandable;
}

Result

Verify the result.

Tree

Details

    As first, we ve created tree using mat-tree and mat-tree-node.

    Then, we ve created the data source in ts file and bind it with mat-tree.

Advertisements