Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/445.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript TreeView-检查是否展开并单击_Javascript_Reactjs - Fatal编程技术网

Javascript TreeView-检查是否展开并单击

Javascript TreeView-检查是否展开并单击,javascript,reactjs,Javascript,Reactjs,我正在使用Material UI中的TreeView组件构建一个TreeView: 我已经创建了下面的组件,当节点展开时,该组件将获取数据。此外,树是构建的,因此每个有子节点的节点也是一棵树,但我有两个问题: 问题1: 现在,每次展开节点时都会调用fetchChildNodes。我想更改此设置,以便检查当前节点之前是否已展开。如果它已展开,我不想调用fetchChildNodes,而是使用先前获取的数据。这是因为节点的I可以展开、关闭并再次展开,在此过程中,fetchChildNodes将被调用

我正在使用Material UI中的TreeView组件构建一个
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文档检查以下内容: