Angular Material 7 – Tree


Angular Material 7 – Tree


”;


The <mat-tree>, an Angular Directive, is used to create a tree with material styling 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(
      public expandable: boolean, public filename: string, public level: number, public 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.initialize();
   }
   initialize() {
      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

”;

Leave a Reply

Your email address will not be published. Required fields are marked *