Javascript TreeView-检查是否展开并单击
我正在使用Material UI中的TreeView组件构建一个Javascript TreeView-检查是否展开并单击,javascript,reactjs,Javascript,Reactjs,我正在使用Material UI中的TreeView组件构建一个TreeView: 我已经创建了下面的组件,当节点展开时,该组件将获取数据。此外,树是构建的,因此每个有子节点的节点也是一棵树,但我有两个问题: 问题1: 现在,每次展开节点时都会调用fetchChildNodes。我想更改此设置,以便检查当前节点之前是否已展开。如果它已展开,我不想调用fetchChildNodes,而是使用先前获取的数据。这是因为节点的I可以展开、关闭并再次展开,在此过程中,fetchChildNodes将被调用
TreeView
:
我已经创建了下面的组件,当节点展开时,该组件将获取数据。此外,树是构建的,因此每个有子节点的节点也是一棵树,但我有两个问题:
问题1:
现在,每次展开节点时都会调用fetchChildNodes
。我想更改此设置,以便检查当前节点之前是否已展开。如果它已展开,我不想调用fetchChildNodes
,而是使用先前获取的数据。这是因为节点的I可以展开、关闭并再次展开,在此过程中,fetchChildNodes
将被调用两次。我怎么检查这个
问题2:
是否有某种onClick
方法可以为单击的节点提供nodeId
?expandingNodes
仅为可扩展节点提供nodeId
,而不是leaf
节点
import ReactDOM from "react-dom";
import React from "react";
import TreeView from "@material-ui/lab/TreeView";
import ExpandMoreIcon from "@material-ui/icons/ExpandMore";
import ChevronRightIcon from "@material-ui/icons/ChevronRight";
import TreeItem from "@material-ui/lab/TreeItem";
const { useState, useCallback } = React;
export default function MyTreeItem(props) {
const [childNodes, setChildNodes] = useState(null);
const [expanded, setExpanded] = React.useState([]);
function fetchChildNodes(id) {
return new Promise(resolve => {
setTimeout(() => {
resolve({
children: [
{
id: "2",
name: "Calendar"
},
{
id: "3",
name: "Settings"
},
{
id: "4",
name: "Music"
}
]
});
}, 1000);
});
}
const handleChange = (event, nodes) => {
const expandingNodes = nodes.filter(x => !expanded.includes(x));
setExpanded(nodes);
if (expandingNodes[0]) {
const childId = expandingNodes[0];
fetchChildNodes(childId).then(result =>
setChildNodes(
result.children.map(node => <MyTreeItem key={node.id} {...node} />)
)
);
}
};
return (
<TreeView
defaultCollapseIcon={<ExpandMoreIcon />}
defaultExpandIcon={<ChevronRightIcon />}
expanded={expanded}
onNodeToggle={handleChange}
>
{/*The node below should act as the root node for now */}
<TreeItem nodeId={props.id} label={props.name}>
{childNodes || [<div key="stub" />]}
</TreeItem>
</TreeView>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<MyTreeItem id="1" name="Applications" />, rootElement);
从“react-dom”导入ReactDOM;
从“React”导入React;
从“@material ui/lab/TreeView”导入TreeView;
从“@material ui/icons/ExpandMore”导入ExpandMoreIcon;
从“@material ui/icons/ChevronRight”导入ChevronRightIcon;
从“@material ui/lab/TreeItem”导入TreeItem;
const{useState,useCallback}=React;
导出默认函数MyTreeItem(道具){
常量[childNodes,setChildNodes]=useState(null);
const[expanded,setExpanded]=React.useState([]);
函数fetchChildNodes(id){
返回新承诺(解决=>{
设置超时(()=>{
决心({
儿童:[
{
id:“2”,
名称:“日历”
},
{
id:“3”,
名称:“设置”
},
{
id:“4”,
名称:“音乐”
}
]
});
}, 1000);
});
}
常量handleChange=(事件、节点)=>{
const expandingNodes=nodes.filter(x=>!expanded.includes(x));
集合(节点);
if(展开节点[0]){
const childId=expandingNodes[0];
fetchChildNodes(childId)。然后(结果=>
setChildNodes(
result.children.map(节点=>)
)
);
}
};
返回(
{/*下面的节点现在应充当根节点*/}
{childNodes | |[]}
);
}
const rootElement=document.getElementById(“根”);
render(,rootElement);
回答问题2:
只需将自定义标签对象添加到树项:
import ReactDOM from "react-dom";
import React from "react";
import TreeView from "@material-ui/lab/TreeView";
import ExpandMoreIcon from "@material-ui/icons/ExpandMore";
import ChevronRightIcon from "@material-ui/icons/ChevronRight";
import TreeItem from "@material-ui/lab/TreeItem";
const { useState, useCallback } = React;
export default function MyTreeItem(props) {
const [childNodes, setChildNodes] = useState(null);
const [expanded, setExpanded] = React.useState([]);
function fetchChildNodes(id) {
return new Promise(resolve => {
setTimeout(() => {
resolve({
children: [
{
id: "2",
name: "Calendar"
},
{
id: "3",
name: "Settings"
},
{
id: "4",
name: "Music"
}
]
});
}, 1000);
});
}
const handleChange = (event, nodes) => {
const expandingNodes = nodes.filter(x => !expanded.includes(x));
setExpanded(nodes);
if (expandingNodes[0]) {
const childId = expandingNodes[0];
fetchChildNodes(childId).then(result =>
setChildNodes(
result.children.map(node => (
<MyTreeItem key={node.id} {...node} />
))
)
);
}
};
const renderLabel = item => (
<span
onClick={event => {
console.log(item.id);
//setActiveItemId(item.id);
// if you want after click do expand/collapse comment this two line
event.stopPropagation();
event.preventDefault();
}}
>
{item.name}
</span>
);
return (
<TreeView
defaultCollapseIcon={<ExpandMoreIcon />}
defaultExpandIcon={<ChevronRightIcon />}
expanded={expanded}
onNodeToggle={handleChange}
>
{/*The node below should act as the root node for now */}
<TreeItem nodeId={props.id} label={renderLabel(props)}>
{childNodes || [<div key="stub" />]}
</TreeItem>
</TreeView>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(
<MyTreeItem id="1" name="Applications" />,
rootElement
);
从“react-dom”导入ReactDOM;
从“React”导入React;
从“@material ui/lab/TreeView”导入TreeView;
从“@material ui/icons/ExpandMore”导入ExpandMoreIcon;
从“@material ui/icons/ChevronRight”导入ChevronRightIcon;
从“@material ui/lab/TreeItem”导入TreeItem;
const{useState,useCallback}=React;
导出默认函数MyTreeItem(道具){
常量[childNodes,setChildNodes]=useState(null);
const[expanded,setExpanded]=React.useState([]);
函数fetchChildNodes(id){
返回新承诺(解决=>{
设置超时(()=>{
决心({
儿童:[
{
id:“2”,
名称:“日历”
},
{
id:“3”,
名称:“设置”
},
{
id:“4”,
名称:“音乐”
}
]
});
}, 1000);
});
}
常量handleChange=(事件、节点)=>{
const expandingNodes=nodes.filter(x=>!expanded.includes(x));
集合(节点);
if(展开节点[0]){
const childId=expandingNodes[0];
fetchChildNodes(childId)。然后(结果=>
setChildNodes(
result.children.map(节点=>(
))
)
);
}
};
const renderLabel=项目=>(
{
console.log(item.id);
//setActiveItemId(item.id);
//如果您想在单击展开/折叠后对这两行进行注释
event.stopPropagation();
event.preventDefault();
}}
>
{item.name}
);
返回(
{/*下面的节点现在应充当根节点*/}
{childNodes | |[]}
);
}
const rootElement=document.getElementById(“根”);
ReactDOM.render(
,
根元素
);
问题2答案:您可以在
树状视图上使用onNodeSelect={action}
,操作如下
function action(event, nodeId) {
console.log('nodeId: ', nodeId)
}
谢谢你的回答,但似乎什么也没发生。这对我来说很有用。请参阅我帖子中的屏幕截图,请参阅TreeItem API文档检查以下内容: