我想从一组值中动态填充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>
);
}
}
答案 0 :(得分:1)
这是一个有效的代码: 我必须解决的第一个问题是我的异步&#39;关键字,请参阅注释。 然后这行有效:menuItems = {createActions(this.state.actions)}
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;