React material-ui菜单:如何动态填充嵌套菜单?

时间:2018-04-10 14:22:22

标签: dynamic menu material-ui

我想从一组值中动态填充MenuItem(https://www.material-ui.com/#/components/menu)的'menuItems'属性。 我发现了几篇关于使用map语法的帖子,事实上我设法让它用MenuItem元素填充Menu。但是我没有设法填充menuItems数组(嵌套菜单)。

任何帮助表示感谢,我是新的反应和JavaScript,所以很可能我错过了一些明显的东西。 感谢

这是我写的:

class PopupMenu extends React.Component {
  constructor(props) {
    super(props);
    this.state = { menu: props.menu, key: (props.menu.id + "_menu"), open: false, actions: null};
  }

  
...
  
  async createActionOrMenu(actionOrMenu) {
	  if (actionOrMenu[1] == true) {
		  // submenu
		  let menu = actionOrMenu[0];
		  let actionsOrMenus = await window.epic.content(menu);
		  return <MenuItem 
			  primaryText={label(menu.title)} 
			  menuItems={actionsOrMenus.map(this.createActionOrMenu.bind(this))} // the line I have problem with
		  />
	  } else {
		  //action
		  let action = actionOrMenu[0];
		  return <MenuAction action={action}/>
	  }
  }
  
  createActions(actionsOrMenus) {
	  if (!actionsOrMenus || actionsOrMenus.length === 0) {
		  return;
	  }
	  return actionsOrMenus.map(this.createActionOrMenu.bind(this)); // the map syntax to dynamically fill elements: works like charm
  }

  render() {
    return (
      <div>
        <FlatButton
		  className="menubar_menu"
          onClick={this.handleClick}
          label={label(this.state.menu.title)}
		  hoverColor="lightgrey"
		  primary = {this.state.open}
        />
        <Popover
          open={this.state.open}
          anchorEl={this.state.anchorEl}
          anchorOrigin={{horizontal: 'left', vertical: 'bottom'}}
          targetOrigin={{horizontal: 'left', vertical: 'top'}}
          onRequestClose={this.handleRequestClose}
        >				  
          <Menu key= {this.state.key+"popup"}>
		        {this.createActions(this.state.actions)}
          </Menu>
        </Popover>
      </div>
    );
  }
}

1 个答案:

答案 0 :(得分:1)

这是一个有效的代码: 我必须解决的第一个问题是我的异步&#39;关键字,请参阅注释。 然后这行有效:menuItems = {createActions(this.state.actions)}

&#13;
&#13;
class MenuAction extends React.Component {
	constructor(props) {
		super(props);
		this.state = {action: props.action};
	}
	
	render () {
		return (
			<MenuItem primaryText={label(this.state.action.text)}/>
		);
	}
}

function createActionOrMenu(actionOrMenu) {
  if (!actionOrMenu || !actionOrMenu[0]) {
		console.error("invalid action/menu sent to createActionOrMenu");
		return;
	}
  if (actionOrMenu[1] == true) {
	  // submenu
	  return <SubMenu menu= {actionOrMenu[0]} key = {actionOrMenu[0].id + "_submenu"} />
  } else {
	  // action
	  return <MenuAction action= {actionOrMenu[0]} key = {actionOrMenu[0].id + "_action"}/>
  }
}

function createActions(actionsOrMenus) {
	if (!actionsOrMenus || actionsOrMenus.length === 0) {
		return;
	}
	return actionsOrMenus.map(createActionOrMenu);
}
  
  

class SubMenu extends React.Component {
	constructor(props) {
		super(props);
		this.state = { menu: props.menu, actions: []};
	}
	
	UNSAFE_componentWillMount() {
	  this.init();
	}
  
	async init() {
		let content = await window.epic.currentPage.menuBarSite.content(this.state.menu);
		this.setState({actions: content});  
	}	
	  
	 render() {
		 return <MenuItem 
			primaryText={label(this.state.menu.title)} 
			key={this.state.menu.title}
			menuItems={createActions(this.state.actions)}  // this works
		  />
	 }
}

class PopupMenu extends React.Component {
  constructor(props) {
    super(props);
    this.state = {menu: props.menu, actions: [], open: false};
  }

  UNSAFE_componentWillMount() {
	  this.init();
  }
  
  async init() {
	  let content = await window.epic.currentPage.menuBarSite.content(this.state.menu);
	  this.setState({actions: content});  
  }
  
  handleClick = (event) => {
    // This prevents ghost click.
    event.preventDefault();

    this.setState({
      open: true,
      anchorEl: event.currentTarget,
    });
  };

  handleRequestClose = () => {
    this.setState({
      open: false,
    });
  };
  

  render() {
    return (
      <div>
        <FlatButton
		  className="menubar_menu"
          onClick={this.handleClick}
          label={label(this.state.menu.title)}
		  hoverColor="lightgrey"
		  primary = {this.state.open}
        />
        <Popover
          open={this.state.open}
          anchorEl={this.state.anchorEl}
          anchorOrigin={{horizontal: 'left', vertical: 'bottom'}}
          targetOrigin={{horizontal: 'left', vertical: 'top'}}
          onRequestClose={this.handleRequestClose}
        >				  
          <Menu key= {this.state.key+"_popup"}>
		    {createActions(this.state.actions)}
          </Menu>
        </Popover>
      </div>
    );
  }
}
&#13;
&#13;
&#13;