Angular Material 7 树


The <垫树> ,一个 Angular 指令,用于创建具有材质样式的树以显示分层数据。

在本章中,我们将展示使用 Angular Material 绘制树所需的配置。

以下是修改后的模块描述符的内容 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 { }

以下是修改后的 HTML 主机文件的内容 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>

以下是修改后的ts文件内容 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


验证结果。

Tree

Details


  • 首先,我们使用 mat-tree 和 mat-tree-node 创建了树。
  • 然后,我们在 ts 文件中创建了数据源,并将其与 mat-tree 绑定。