带有子项的Material UI菜单不会关闭整个菜单

时间:2019-10-01 10:18:19

标签: javascript reactjs material-ui

我有一个带有自定义MenuItems的Material UI菜单组件。现在,当菜单和子菜单打开时,我希望能够在菜单外部单击时关闭整个菜单。我仍然需要单击两次,首先关闭子菜单,然后关闭实际菜单。

文档MUI menu涉及使用anchorEl作为boolean来确定菜单是否打开,但是即使我从自定义菜单项发送close回调函数,它也只能通过关闭自身来关闭在组件外部单击时的handleClose()。因此,在所附图片中,仅关闭了包含公司财务的容器,而没有关闭菜单。

无法理解,由于anchorElcloseFunction中变为null,因此核心菜单仍然保持打开状态。尝试使用基于Modal组件的menu和MenuItems和Popover。

MenuComponent

const MoreMenu = ({
  userTagData,
  onChangeItemName,
  selectedTags,
  onTagSelected,
  onRemoveItem,
  data,
  item,
}) => {
  const [anchorEl, setAnchorEl] = useState(null);
  const [subMenuPopUpName, setSubMenuPopUpName] = useState('');


  const renderChangeTitlePopUp = () => (
    <ChangeTitleContainer
      onChangeItemName={onChangeItemName}
      closeMenuItem={handleClose}
      item={item}
    />
  );


  const renderAddTagPopUp = () => (
    <AddTagContainer
      item={item}
      userTagData={userTagData}
      selectedTags={selectedTags}
      onTagSelected={onTagSelected}
    />
  );

  const renderRemoveItemContainer = () => (
    <RemoveItemContainer
      item={item}
      onRemoveItem={onRemoveItem}
      closeMenuItem={handeleClose}
    />
  );

  const renderDefaultPopup = () => (
    <div><p>Standard menu post</p></div>
  );


  const menuItemPopUpSwitcher = (name) => {
    switch (name) {
      case ADDTAG:
        return renderAddTagPopUp();
      case CHANGETITLE:
        return renderChangeTitlePopUp();
      case REMOVEITEM:
        return renderRemoveItemContainer();
      default:
        return renderDefaultPopup();
    }
  };

  const handleMenuItemClick = (item, event) => {
    setAnchorEl(event.currentTarget);
    setSubMenuPopUpName(item.title);
    setAnchorEl(event.currentTarget);
    menuItemPopUpSwitcher(item);
  };

  const handleClose = () => {
    setAnchorEl(null);
  };

  return (
    <Fragment>
      <MoreButton
        data={data}
        handleMenuItemClick={handleMenuItemClick}
      />
      <Menu
        open={Boolean(anchorEl)}
        anchorEl={anchorEl}
        onClose={handleClose}
        anchorOrigin={{
          vertical: 'top',
          horizontal: 'left',
        }}
        transformOrigin={{
          vertical: 'top',
          horizontal: 'right',
        }}
      >

        {menuItemPopUpSwitcher(subMenuPopUpName)}

      </Menu>
    </Fragment>
  );
};custom 

subme nuopen

1 个答案:

答案 0 :(得分:1)

能够通过为父锚添加另一个状态来解决问题。因此,父菜单具有其自己的锚,子菜单弹出其自身的锚,然后handleClose()禁用它们。请参见示例和5行标有///这是新的:

const MoreMenu = ({
  userTagData,
  onChangeItemName,
  selectedTags,
  onTagSelected,
  onRemoveItem,
  data,
  item,
}) => {
  const [parentAnchorEl, setParentAnchorEl] = useState(null); // THIS IS NEW
  const [anchorEl, setAnchorEl] = useState(null);
  const [subMenuPopUpName, setSubMenuPopUpName] = useState('');

  const handleMoreButtonClick = (event) => { // THIS IS NEW
    setParentAnchorEl(event.currentTarget);
  };

  const renderChangeTitlePopUp = () => (
    <ChangeTitleContainer
      onChangeItemName={onChangeItemName}
      closeMenuItem={handleClose}
      item={item}
    />
  );


  const renderAddTagPopUp = () => (
    <AddTagContainer
      item={item}
      userTagData={userTagData}
      selectedTags={selectedTags}
      onTagSelected={onTagSelected}
    />
  );

  const renderRemoveItemContainer = () => (
    <RemoveItemContainer
      item={item}
      onRemoveItem={onRemoveItem}
      closeMenuItem={handeleClose}
    />
  );

  const renderDefaultPopup = () => (
    <div><p>Standard menu post</p></div>
  );


  const menuItemPopUpSwitcher = (name) => {
    switch (name) {
      case ADDTAG:
        return renderAddTagPopUp();
      case CHANGETITLE:
        return renderChangeTitlePopUp();
      case REMOVEITEM:
        return renderRemoveItemContainer();
      default:
        return renderDefaultPopup();
    }
  };

  const handleMenuItemClick = (item, event) => {
    setAnchorEl(event.currentTarget);
    setSubMenuPopUpName(item.title);
    setAnchorEl(event.currentTarget);
    menuItemPopUpSwitcher(item);
  };

  const handleClose = () => {
    setAnchorEl(null);
    setParentAnchorEl(null); //THIS IS NEW
  };

  return (
    <Fragment>
      <MoreButton
        anchorEl={parentAnchorEl} //THIS IS NEW
        data={data}
        handleMenuItemClick={handleMenuItemClick}
        handleClick={handleMoreButtonClick}    //THIS IS NEW
      />
      <Menu
        open={Boolean(anchorEl)}
        anchorEl={anchorEl}
        onClose={handleClose}
        anchorOrigin={{
          vertical: 'top',
          horizontal: 'left',
        }}
        transformOrigin={{
          vertical: 'top',
          horizontal: 'right',
        }}
      >

        {menuItemPopUpSwitcher(subMenuPopUpName)}

      </Menu>
    </Fragment>
  );
};custom