Mat-tree 创建一个带有要显示的值和 ids 的树 [英] Mat-tree create a tree with values to display and ids
问题描述
我正在按照文档学习如何使用 mat-tree,但现在我需要使用一个数据源树,它不仅定义了字符串,因为当我单击一个节点时,我需要知道它的 id.
是否有我想要实现的数据为 JSON、具有属性等的工作示例?
我真的相信关于树视图的例子更复杂.想象一下你有一些喜欢
const TREE_DATA: FoodNode[] = [{名称: "水果",孩子们: [{名称:苹果",ID:1},{名称:香蕉",ID:2},{名称:水果循环",ID:3}]},{name: "蔬菜",孩子们: [{名称:绿色",孩子们: [{名称:西兰花",ID:4},{名称:抱子甘蓝",ID:5}]},{名称:橙色",孩子们:[{名称:南瓜",id:6},{名称:胡萝卜",id:7}]}]}];
如果你在你的 FoodNode 界面中添加一些辅助属性:selected、parent 和 indeterminate
接口 FoodNode {名称:字符串;身份证号码;选择?:布尔值;不确定?:布尔值;父母?:FoodNode孩子?:FoodNode[];}
这里的关键是知道父母",所以,当我们打开一张支票时,询问他的父母
setParent(data, parent) {data.parent = 父母;如果(数据.孩子){data.children.forEach(x => {this.setParent(x, 数据);});}}
你可以写一个 .html 之类的
<!-- 这是叶子节点的树节点模板--><mat-tree-node *matTreeNodeDef="let node" matTreeNodeToggle><li class="mat-tree-node"><!-- 使用禁用按钮为树叶提供填充 --><按钮垫图标按钮禁用></button><mat-checkbox class="checklist-leaf-node"(change)="todoItemSelectionToggle($event.checked,node)"[选中]="node.selected">{{node.name}}</mat-checkbox></mat-tree-node><!-- 这是可扩展节点的树节点模板--><mat-nested-tree-node *matTreeNodeDef="let node; when: hasChild"><li><div class="mat-tree-node"><button mat-icon-button matTreeNodeToggle[attr.aria-label]="'toggle' + node.name"><mat-icon class="mat-icon-rtl-mirror">{{treeControl.isExpanded(节点)?'expand_more':'chevron_right'}}</mat-icon>按钮><mat-checkbox [选中]="node.selected"[indeterminate]="node.indeterminate && !node.selected"(change)="todoItemSelectionToggle($event.checked,node)">{{node.name}}</mat-checkbox>
<ul [class.example-tree-invisible]="!treeControl.isExpanded(node)"><ng-container matTreeNodeOutlet></ng-container></mat-nested-tree-node></mat-tree>
其他功能是
treeControl = new NestedTreeControl(node => node.children);dataSource = new MatTreeNestedDataSource();构造函数(){this.dataSource.data = TREE_DATA;Object.keys(this.dataSource.data).forEach(x => {this.setParent(this.dataSource.data[x], null);});}hasChild = (_: number, node: FoodNode) =>!!node.children &&node.children.length >0;checkAllParents(节点){如果(节点.父){const 后代 = this.treeControl.getDescendants(node.parent);node.parent.selected=descendants.every(child => child.selected);node.parent.indeterminate=descendants.some(child => child.selected);this.checkAllParents(node.parent);}}todoItemSelectionToggle(选中,节点){node.selected = 选中;如果(节点.孩子){node.children.forEach(x => {this.todoItemSelectionToggle(checked, x);});}this.checkAllParents(node);}}提交() {让结果 = [];this.dataSource.data.forEach(node => {结果 = result.concat(this.tree控件.getDescendants(节点).filter(x => x.selected && x.id).map(x => x.id));});控制台日志(结果);}
stackblitz,这里
I'm learning how to use mat-tree following the docs, but now I need to use a data source tree that has not only strings defined in it, because when I click a node I need to know its id.
This is the stackblitz of my project.
Basically I need to use this tree with checkboxes that I've built following the docs, but now my data source is this:
const TREE_DATA:TodoItemNode = {
item: "First item",
children: [{
item: 'Second item',
children:[
{
item: "Third item",
id: 3
}
],
id:2
}],
id:1
}
So I want to display as text the value of item and then get the "id" when that node is clicked. Currently I can't make it work and I only see these tree nodes:
Is there a working example for data as JSON, with properties etc. as I want to achieve?
Really I beleive the example about tree-view is more complex. Imagine you has some like
const TREE_DATA: FoodNode[] = [
{
name: "Fruit",
children: [
{ name: "Apple", id: 1 },
{ name: "Banana", id: 2 },
{ name: "Fruit loops", id: 3 }
]
},
{
name: "Vegetables",
children: [
{
name: "Green",
children: [
{ name: "Broccoli", id: 4 },
{ name: "Brussel sprouts", id: 5 }
]
},
{
name: "Orange",
children: [{ name: "Pumpkins", id: 6 }, { name: "Carrots", id: 7 }]
}
]
}
];
If you add to your FoodNode interface some auxiliars properties: selected,parent and indeterminate
interface FoodNode {
name: string;
id?: number;
selected?: boolean;
indeterminate?:boolean;
parent?:FoodNode
children?: FoodNode[];
}
The key here is know the "parent", so, when we toogle one check, ask about his parent
setParent(data, parent) {
data.parent = parent;
if (data.children) {
data.children.forEach(x => {
this.setParent(x, data);
});
}
}
You can write an .html like
<mat-tree [dataSource]="dataSource" [treeControl]="treeControl" class="example-tree">
<!-- This is the tree node template for leaf nodes -->
<mat-tree-node *matTreeNodeDef="let node" matTreeNodeToggle>
<li class="mat-tree-node">
<!-- use a disabled button to provide padding for tree leaf -->
<button mat-icon-button disabled></button>
<mat-checkbox class="checklist-leaf-node"
(change)="todoItemSelectionToggle($event.checked,node)"
[checked]="node.selected"
>{{node.name}}</mat-checkbox>
</li>
</mat-tree-node>
<!-- This is the tree node template for expandable nodes -->
<mat-nested-tree-node *matTreeNodeDef="let node; when: hasChild">
<li>
<div class="mat-tree-node">
<button mat-icon-button matTreeNodeToggle
[attr.aria-label]="'toggle ' + node.name">
<mat-icon class="mat-icon-rtl-mirror">
{{treeControl.isExpanded(node) ? 'expand_more' : 'chevron_right'}}
</mat-icon>
</button>
<mat-checkbox [checked]="node.selected"
[indeterminate]="node.indeterminate && !node.selected"
(change)="todoItemSelectionToggle($event.checked,node)">
{{node.name}}</mat-checkbox>
</div>
<ul [class.example-tree-invisible]="!treeControl.isExpanded(node)">
<ng-container matTreeNodeOutlet></ng-container>
</ul>
</li>
</mat-nested-tree-node>
</mat-tree>
Anothers functions are
treeControl = new NestedTreeControl<FoodNode>(node => node.children);
dataSource = new MatTreeNestedDataSource<FoodNode>();
constructor() {
this.dataSource.data = TREE_DATA;
Object.keys(this.dataSource.data).forEach(x => {
this.setParent(this.dataSource.data[x], null);
});
}
hasChild = (_: number, node: FoodNode) =>
!!node.children && node.children.length > 0;
checkAllParents(node) {
if (node.parent) {
const descendants = this.treeControl.getDescendants(node.parent);
node.parent.selected=descendants.every(child => child.selected);
node.parent.indeterminate=descendants.some(child => child.selected);
this.checkAllParents(node.parent);
}
}
todoItemSelectionToggle(checked, node) {
node.selected = checked;
if (node.children) {
node.children.forEach(x => {
this.todoItemSelectionToggle(checked, x);
});
}
this.checkAllParents(node);
}
}
submit() {
let result = [];
this.dataSource.data.forEach(node => {
result = result.concat(
this.treeControl
.getDescendants(node)
.filter(x => x.selected && x.id)
.map(x => x.id)
);
});
console.log(result);
}
The stackblitz, here
这篇关于Mat-tree 创建一个带有要显示的值和 ids 的树的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!