Angular Material 7-树
在Angular Material 7中,我们可以使用mat-tree组件来实现树形结构。mat-tree组件是一个高度可定制的组件,用于呈现树形数据。它允许我们轻松地绘制可折叠、展开和选择的树。
创建mat-tree
要创建一个mat-tree组件,需要引入MatTreeModule到我们的模块中。使用mat-tree的方式与其他Angular Material组件的使用方式非常相似,首先要导入模块:
import {MatTreeModule} from '@angular/material/tree';
@NgModule({
imports: [
MatTreeModule
]
})
export class AppModule { }
现在我们可以创建我们的树,在本例中,我们将使用基于JSON的数据源来创建一个简单的树。首先,我们将创建一个组件以包含树,然后我们将创建一个组件以表示树节点。
import {Component} from '@angular/core';
/**
* 树节点数据
*/
interface FoodNode {
name: string;
children?: FoodNode[];
}
const TREE_DATA: FoodNode[] = [
{
name: '水果',
children: [
{name: '苹果'},
{name: '香蕉'},
{name: '橙子'},
]
}, {
name: '蔬菜',
children: [
{
name: '根菜类',
children: [
{name: '大白菜'},
{name: '胡萝卜'},
]
}, {
name: '叶菜类',
children: [
{name: '菠菜'},
{name: '油菜'},
]
}
]
},
];
@Component({
selector: 'app-tree',
template: `
<mat-tree [dataSource]="dataSource">
<!-- This is the tree node template for leaf nodes -->
<mat-tree-node *matTreeNodeDef="let node" matTreeNodePadding>
<!-- use a disabled button to provide padding for tree leaf -->
<button mat-icon-button disabled></button>
{{node.name}}
</mat-tree-node>
<!-- This is the tree node template for expandable nodes -->
<mat-tree-node *matTreeNodeDef="let node;when: hasChild" matTreeNodePadding>
<button mat-icon-button matTreeNodeToggle
[attr.aria-label]="'Toggle ' + node.name">
<mat-icon class="rotated-icon"
[attr.aria-label]="'Toggle ' + node.name">
{{treeControl.isExpanded(node) ? 'expand_more' : 'chevron_right'}}
</mat-icon>
</button>
{{node.name}}
</mat-tree-node>
</mat-tree>
`
})
export class TreeComponent {
treeControl = new NestedTreeControl<FoodNode>(node => node.children);
dataSource = new MatTreeNestedDataSource<FoodNode>();
constructor() {
this.dataSource.data = TREE_DATA;
}
hasChild = (_: number, node: FoodNode) => !!node.children && node.children.length > 0;
}
这就是我们的mat-tree组件。在这个例子中,我们创建了一个简单的树形结构来表示食品类别和子类别。接下来,我们将逐步了解这个组件并看看如何自定义它。
Tree Node定义
在这个例子中,我们只需要创建一个树节点组件来表示节点本身。这个组件将被mat-tree组件使用,它有两种形式:
- Leaf Node:这是没有子节点的节点,通常用于末节点。
- Expandable node:这是可以展开的父节点,它可以使用按钮来折叠和展开它的子节点。
我们可以使用以下模板来定义我们的节点。
<mat-tree-node *matTreeNodeDef="let node" matTreeNodePadding>
<button mat-icon-button disabled></button>
{{node.name}}
</mat-tree-node>
<mat-tree-node *matTreeNodeDef="let node;when: hasChild" matTreeNodePadding>
<button mat-icon-button matTreeNodeToggle
[attr.aria-label]="'Toggle ' + node.name">
<mat-icon class="rotated-icon"
[attr.aria-label]="'Toggle ' + node.name">
{{treeControl.isExpanded(node) ? 'expand_more' : 'chevron_right'}}
</mat-icon>
</button>
{{node.name}}
</mat-tree-node>
在这个模板中,我们使用*matTreeNodeDef来指定什么样的节点会被呈现。我们使用hasChild方法来指定哪个节点可以被折叠。在节点中,我们使用matTreeNodeToggle指令来添加一个用于切换节点的按钮。
TreeControl和DataSource
树的控制和数据源是通过Angular Material提供的两个类来处理的:MatTreeControl和MatTreeDataSource。
MatTreeControl允许我们控制如何展开和折叠节点以及选择节点。MatTreeDataSource处理我们的数据源并使其符合mat-tree组件的要求。
在我们的例子中,我们在TreeComponent中创建了一个treeControl和一个dataSource。
treeControl = new NestedTreeControl<FoodNode>(node => node.children);
dataSource = new MatTreeNestedDataSource<FoodNode>();
如您所见,我们使用了NestedTreeControl,因为我们的数据是嵌套的。如果我们只有一层数据,我们可以使用FlatTreeControl。
在我们的构造函数中,我们将我们的数据源绑定到我们的dataSource属性上:
constructor() {
this.dataSource.data = TREE_DATA;
}
Conclusion
我们已经看到了如何使用mat-tree组件创建一个基本的树,在这个例子中,我们使用了一个JSON文件来创建一个嵌套的数据源。我们还了解了如何使用MatTreeControl和MatTreeDataSource来管理我们的树的行为和数据源。在您的项目中,您可以使用更丰富的数据源和更复杂的行为来创建定制的树。