简体   繁体   English

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

[英]Material UI Menu with subitems won't close whole menu

I have a Material UI menu component with custom MenuItems.我有一个带有自定义 MenuItems 的 Material UI 菜单组件。 Now when the menu and a submenu is opened I would like to be able to close the whole menu when clicking outside of the menu.现在,当打开菜单和子菜单时,我希望能够在单击菜单外部时关闭整个菜单。 I still need to do two clicks, first closing the submenu and then the actual menu.我仍然需要单击两次,首先关闭子菜单,然后关闭实际菜单。

The documentation MUI menu refers to using the anchorEl as the boolean to determine if menu is open but even i send the close callback function from the custom menu items it only closes itself with the handleClose() when clicking outside the component.文档MUI 菜单是指使用anchorEl作为boolean来确定菜单是否打开,但即使我从自定义菜单项发送关闭回调 function,它也只会在单击组件外部时使用handleClose()自行关闭。 So in the picture attached only the Container containing Corporate finance is closed and not also the menu.因此,在所附图片中,仅包含企业财务的容器已关闭,菜单也未关闭。

Can't understand, as the anchorEl is turning to null in the closeFunction the core menu still stays open.无法理解,因为 anchorEl 在anchorEl中转向closeFunction核心菜单仍然保持打开状态。 Tried with menu and MenuItems and Popover that are built on the Modal component.尝试使用基于 Modal 组件构建的菜单和 MenuItems 和 Popover。

MenuComponent : 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 

子菜单打开

Was able to solve problem by adding another state for the parent anchor.能够通过为父锚添加另一个 state 来解决问题。 So the parent menu has its own anchor and the child popup its own anchor and then handleClose() disables them both.所以父菜单有自己的锚点,子菜单弹出自己的锚点,然后 handleClose() 禁用它们。 See example and 5 lines marked with //THIS IS NEW:请参阅示例和标有 //这是新的 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 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM