首页 > 解决方案 > Material-UI TreeView - 如何获取被点击的 TreeItem 的 nodeId?

问题描述

我正在使用Material UIs Tree View,我想在nodeId单击图标时获取该项目的道具或 。如何做到这一点?基本上,我想要一个删除图标,它会调用 API 来根据节点的 ID 删除节点。

在他们的例子中,他们正在传递props,但是当我这些道具时MinusSquare,它们是空的。PlusSquareconsole.log

function MinusSquare(props) {
 return (
   <SvgIcon fontSize="inherit" style={{ width: 14, height: 14 }} {...props}>
    ...
   </SvgIcon>
 );
}
...
<TreeView
  aria-label="customized"
  className={classes.root}
  defaultExpanded={['1']}
  defaultCollapseIcon={<MinusSquare />}
  defaultExpandIcon={<PlusSquare />}
  defaultEndIcon={<CloseSquare />}
>
  <StyledTreeItem nodeId="1" label="Main"> <!--- get these nodeId values and/or other props --->
    <StyledTreeItem nodeId="2" label="Hello" />
    <StyledTreeItem nodeId="3" label="Subtree with children">
      <StyledTreeItem nodeId="6" label="Hello" />
      <StyledTreeItem nodeId="7" label="Sub-subtree with children">
        <StyledTreeItem nodeId="9" label="Child 1" />
        <StyledTreeItem nodeId="10" label="Child 2" />
        <StyledTreeItem nodeId="11" label="Child 3" />
      </StyledTreeItem>
      <StyledTreeItem nodeId="8" label="Hello" />
    </StyledTreeItem>
    <StyledTreeItem nodeId="4" label="World" />
    <StyledTreeItem nodeId="5" label="Something something" />
  </StyledTreeItem>
</TreeView>

标签: reactjsmaterial-ui

解决方案


4.9.13Material -UIonIconClickTreeItem. 由于每个都TreeItem需要附加点击侦听器,因此您应该编写一个包装器组件来重用代码:

function MyTreeItem(props) {
  return (
    <TreeItem
      {...props}
      onIconClick={() => console.log('delete', props.nodeId)}
    />
  );
}

不幸的是,这个道具在 Material-UI5.0.0 alpha-12中被移除了,取而代之的是ContentComponent. 此 API 要求您编写更多代码,以换取更灵活的自定义:

import Typography from "@material-ui/core/Typography";
import IconButton from "@material-ui/core/IconButton";
import DeleteIcon from "@material-ui/icons/Delete";
import TreeView from "@material-ui/lab/TreeView";
import TreeItem, { useTreeItem } from "@material-ui/lab/TreeItem";
import clsx from "clsx";

const CustomContent = React.forwardRef(function CustomContent(props, ref) {
  const {
    classes,
    label,
    nodeId,
    icon: iconProp,
    expansionIcon,
    displayIcon,
    onDelete
  } = props;

  const {
    disabled,
    expanded,
    selected,
    focused,
    handleExpansion,
    handleSelection,
    preventSelection
  } = useTreeItem(nodeId);

  const icon = iconProp || expansionIcon || displayIcon;
  const handleDelete = () => onDelete(nodeId);

  return (
    <div
      className={clsx(classes.root, {
        [classes.expanded]: expanded,
        [classes.selected]: selected,
        [classes.focused]: focused,
        [classes.disabled]: disabled
      })}
      onMouseDown={preventSelection}
      ref={ref}
    >
      <div onClick={handleExpansion} className={classes.iconContainer}>
        {icon}
      </div>
      <IconButton size="small" onClick={handleDelete}>
        <DeleteIcon fontSize="small" />
      </IconButton>
      <Typography
        onClick={handleSelection}
        component="div"
        className={classes.label}
      >
        {label}
      </Typography>
    </div>
  );
});

TreeItem

function MyTreeItem(props) {
  return (
    <TreeItem
      {...props}
      ContentComponent={CustomContent}
      ContentProps={{
        onDelete: (nodeId) => console.log("delete", nodeId)
      }}
    />
  );
}

TreeView

<TreeView
  defaultCollapseIcon={<ExpandMoreIcon />}
  defaultExpandIcon={<ChevronRightIcon />}
  multiSelect
>
  <MyTreeItem nodeId="1" label="Applications">
    <MyTreeItem nodeId="2" label="Calendar" />
    <MyTreeItem nodeId="3" label="Chrome" />
    <MyTreeItem nodeId="4" label="Webstorm" />
  </MyTreeItem>
  <MyTreeItem nodeId="5" label="Documents">
    <MyTreeItem nodeId="6" label="Material-UI">
      <MyTreeItem nodeId="7" label="src">
        <MyTreeItem nodeId="8" label="index.js" />
        <MyTreeItem nodeId="9" label="tree-view.js" />
      </MyTreeItem>
    </MyTreeItem>
  </MyTreeItem>
</TreeView>

现场演示

编辑 ControlledTreeView 材质演示(分叉)


推荐阅读