从自定义对象数组填充树视图。递归调用
Fill treeview from custom array of objects. Recursion call
我正在使用 treeview 来显示我的分层数据。
我有以下对象数组:
const data = [
{ id: 1, hierarchyid: "/", level: 0, name: "Mhz" },
{ id: 2, hierarchyid: "/2/", level: 1, name: "SMT" },
{ id: 3, hierarchyid: "/3/", level: 1, name: "QC" },
{ id: 4, hierarchyid: "/3/4/", level: 2, name: "Tester" },
{ id: 5, hierarchyid: "/3/5/", level: 2, name: "Operator" },
];
我需要用这些数据填充我的树视图。
到目前为止我做了什么:
getTreeItems(node, nodes) {
const filtered = nodes.filter(
(n) => n.hierarchyid.includes(node.hierarchyid) && n.level != node.level
);
return (
<TreeItem
key={node.id}
nodeId={node.hierarchyid}
label={node.name}
onClick={() => onClicked(node)}
>
{filtered.length > 0
? filtered.map((node) => this.getTreeItems(node, filtered))
: null}
</TreeItem>
);
}
和渲染:
render() {
// The data comes from Server
const data = [
{ id: 1, hierarchyid: "/", level: 0, name: "Mhz" },
{ id: 2, hierarchyid: "/2/", level: 1, name: "SMT" },
{ id: 3, hierarchyid: "/3/", level: 1, name: "QC" },
{ id: 4, hierarchyid: "/3/4/", level: 2, name: "Tester" },
{ id: 5, hierarchyid: "/3/5/", level: 2, name: "Operator" },
];
return (
<TreeView
aria-label="file system navigator"
defaultCollapseIcon={<ExpandMoreIcon />}
defaultExpandIcon={<ChevronRightIcon />}
sx={{ height: "auto", flexGrow: 1, width: "auto", overflowY: "auto" }}
>
{this.getTreeItems(
{ id: 1, hierarchyid: "/", level: 0, name: "Mhz" },
data
)}
</TreeView>
);
}
}
这给我的观点是:
+Mhz
+SMT
+QC
+Tester
+Operator
+Tester // they shouldn't be displayed
+Operator // they have already rendered as child under QC
我的问题是无法排除已经渲染的节点。
更新
MUI TreeView 支持其节点的特殊 JSON
数据。所以将 array
转换为 JSON
也解决了问题。类似的东西:
const data = {
id: 1,
hierarchyid: "/",
level: 0,
name: "Mhz",
children: [
{
id: 2,
hierarchyid: "/2/",
level: 1,
name: "SMT"
},
{
id: 3,
hierarchyid: "/3/",
level: 1,
name: "QC",
children: [
{
id: 4,
hierarchyid: "/3/4/",
level: 2,
name: "Tester"
},
{
id: 5,
hierarchyid: "/3/5/",
level: 2,
name: "Operator"
}
]
}
]
};
对象数组来自服务器,那么如何从数组数据中创建这个Json?
所以我查看了文档,他们清楚地提到了一种设计数据对象的方法,这样就可以在不重复多个节点的情况下显示层次结构。
Try going through this once 并根据文档更改渲染函数,您可能会得到想要的结果。
const data: RenderTree = {
id: "root",
name: "Mhz",
children: [
{
id: "1",
name: "SMT"
},
{
id: "3",
name: "QZ",
children: [
{
id: "4",
name: "Tester"
},
{
id: "4",
name: "Operator"
}
]
}
]
};
如果我们编写一个快速函数来测试一个层次结构 id 是否是另一个层次结构的直接后代,那么我们可以用它来编写一个简单的递归版本:
const isChild = (prefix) => ({hierarchyid}) =>
hierarchyid .startsWith (prefix)
&& /^[^\/]*\/$/ .test (hierarchyid .slice (prefix .length))
const nest = (xs, prefix = '') =>
xs .filter (isChild (prefix)) .map ((x, _, __, children = nest (xs, x .hierarchyid)) => ({
...x,
... (children .length ? {children} : {})
}))
const data = [{id: 1, hierarchyid: "/", level: 0, name: "Mhz"}, {id: 2, hierarchyid: "/2/", level: 1, name: "SMT"}, {id: 3, hierarchyid: "/3/", level: 1, name: "QC"}, {id: 4, hierarchyid: "/3/4/", level: 2, name: "Tester"}, {id: 5, hierarchyid: "/3/5/", level: 2, name: "Operator"}]
console .log (nest (data))
.as-console-wrapper {max-height: 100% !important; top: 0}
isChild
检查层次结构 id 是否以我们的前缀开头,如果其余部分只有一个 '/'
,则在最后。
nest
并没有想象中的那么高效,因为它会为每个节点扫描整个数组。但我不会担心,直到我有数万个条目。
如果你不介意在你的叶子上有一些空的 children
数组,它仍然更简单:
const nest = (xs, prefix = '') =>
xs .filter (isChild (prefix)) .map ((x) => ({
...x,
children: nest (xs, x .hierarchyid)
}))
我正在使用 treeview 来显示我的分层数据。
我有以下对象数组:
const data = [
{ id: 1, hierarchyid: "/", level: 0, name: "Mhz" },
{ id: 2, hierarchyid: "/2/", level: 1, name: "SMT" },
{ id: 3, hierarchyid: "/3/", level: 1, name: "QC" },
{ id: 4, hierarchyid: "/3/4/", level: 2, name: "Tester" },
{ id: 5, hierarchyid: "/3/5/", level: 2, name: "Operator" },
];
我需要用这些数据填充我的树视图。 到目前为止我做了什么:
getTreeItems(node, nodes) {
const filtered = nodes.filter(
(n) => n.hierarchyid.includes(node.hierarchyid) && n.level != node.level
);
return (
<TreeItem
key={node.id}
nodeId={node.hierarchyid}
label={node.name}
onClick={() => onClicked(node)}
>
{filtered.length > 0
? filtered.map((node) => this.getTreeItems(node, filtered))
: null}
</TreeItem>
);
}
和渲染:
render() {
// The data comes from Server
const data = [
{ id: 1, hierarchyid: "/", level: 0, name: "Mhz" },
{ id: 2, hierarchyid: "/2/", level: 1, name: "SMT" },
{ id: 3, hierarchyid: "/3/", level: 1, name: "QC" },
{ id: 4, hierarchyid: "/3/4/", level: 2, name: "Tester" },
{ id: 5, hierarchyid: "/3/5/", level: 2, name: "Operator" },
];
return (
<TreeView
aria-label="file system navigator"
defaultCollapseIcon={<ExpandMoreIcon />}
defaultExpandIcon={<ChevronRightIcon />}
sx={{ height: "auto", flexGrow: 1, width: "auto", overflowY: "auto" }}
>
{this.getTreeItems(
{ id: 1, hierarchyid: "/", level: 0, name: "Mhz" },
data
)}
</TreeView>
);
}
}
这给我的观点是:
+Mhz
+SMT
+QC
+Tester
+Operator
+Tester // they shouldn't be displayed
+Operator // they have already rendered as child under QC
我的问题是无法排除已经渲染的节点。
更新
MUI TreeView 支持其节点的特殊 JSON
数据。所以将 array
转换为 JSON
也解决了问题。类似的东西:
const data = {
id: 1,
hierarchyid: "/",
level: 0,
name: "Mhz",
children: [
{
id: 2,
hierarchyid: "/2/",
level: 1,
name: "SMT"
},
{
id: 3,
hierarchyid: "/3/",
level: 1,
name: "QC",
children: [
{
id: 4,
hierarchyid: "/3/4/",
level: 2,
name: "Tester"
},
{
id: 5,
hierarchyid: "/3/5/",
level: 2,
name: "Operator"
}
]
}
]
};
对象数组来自服务器,那么如何从数组数据中创建这个Json?
所以我查看了文档,他们清楚地提到了一种设计数据对象的方法,这样就可以在不重复多个节点的情况下显示层次结构。
Try going through this once 并根据文档更改渲染函数,您可能会得到想要的结果。
const data: RenderTree = {
id: "root",
name: "Mhz",
children: [
{
id: "1",
name: "SMT"
},
{
id: "3",
name: "QZ",
children: [
{
id: "4",
name: "Tester"
},
{
id: "4",
name: "Operator"
}
]
}
]
};
如果我们编写一个快速函数来测试一个层次结构 id 是否是另一个层次结构的直接后代,那么我们可以用它来编写一个简单的递归版本:
const isChild = (prefix) => ({hierarchyid}) =>
hierarchyid .startsWith (prefix)
&& /^[^\/]*\/$/ .test (hierarchyid .slice (prefix .length))
const nest = (xs, prefix = '') =>
xs .filter (isChild (prefix)) .map ((x, _, __, children = nest (xs, x .hierarchyid)) => ({
...x,
... (children .length ? {children} : {})
}))
const data = [{id: 1, hierarchyid: "/", level: 0, name: "Mhz"}, {id: 2, hierarchyid: "/2/", level: 1, name: "SMT"}, {id: 3, hierarchyid: "/3/", level: 1, name: "QC"}, {id: 4, hierarchyid: "/3/4/", level: 2, name: "Tester"}, {id: 5, hierarchyid: "/3/5/", level: 2, name: "Operator"}]
console .log (nest (data))
.as-console-wrapper {max-height: 100% !important; top: 0}
isChild
检查层次结构 id 是否以我们的前缀开头,如果其余部分只有一个 '/'
,则在最后。
nest
并没有想象中的那么高效,因为它会为每个节点扫描整个数组。但我不会担心,直到我有数万个条目。
如果你不介意在你的叶子上有一些空的 children
数组,它仍然更简单:
const nest = (xs, prefix = '') =>
xs .filter (isChild (prefix)) .map ((x) => ({
...x,
children: nest (xs, x .hierarchyid)
}))