Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/jenkins/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reactjs MaterialUI下一个关闭抽屉上的子项单击_Reactjs_Material Ui - Fatal编程技术网

Reactjs MaterialUI下一个关闭抽屉上的子项单击

Reactjs MaterialUI下一个关闭抽屉上的子项单击,reactjs,material-ui,Reactjs,Material Ui,我正在运行MaterialUI Next,我已经尝试了抽屉的所有变体,但当单击抽屉中的项目时,我无法将其关闭。我知道临时变量允许我这样做,但它会在单击任何内容时关闭。我需要它仅在单击ListItem时关闭 在我的例子中,抽屉中有一个扩展面板,其中包含列表和列表项。单击ExpansionPanel不应该关闭抽屉,抽屉应该保持打开状态,因为我还没有准备好离开。但是,当我单击抽屉中的列表项(它们包含component=“a”项)时,抽屉应该关闭,并且component=“a”导航到其href 我的代码

我正在运行MaterialUI Next,我已经尝试了抽屉的所有变体,但当单击抽屉中的项目时,我无法将其关闭。我知道临时变量允许我这样做,但它会在单击任何内容时关闭。我需要它仅在单击ListItem时关闭

在我的例子中,抽屉中有一个扩展面板,其中包含列表和列表项。单击ExpansionPanel不应该关闭抽屉,抽屉应该保持打开状态,因为我还没有准备好离开。但是,当我单击抽屉中的列表项(它们包含
component=“a”
项)时,抽屉应该关闭,并且component=“a”导航到其href

我的代码是非常基本和香草,几乎完全是从。他们也有一个操场来测试代码。但无论如何,这里是我的一些相关代码

我的抽屉:

<Drawer
    variant="persistent" //I tried "temporary", and "permanent" as well
    elevation={16}
    anchor="right"
    open={this.state.open}
    // onClick={(open) => this.setState({ open: false })}
    // onKeyDown={(open) => this.setState({ open: false })}>
    <SystemMenu />
</Drawer>
import React from 'react';
import { withStyles } from 'material-ui-next/styles';
import List, { ListItem, ListItemText } from 'material-ui-next/List';
import ExpansionPanel, { ExpansionPanelDetails, ExpansionPanelSummary } from 'material-ui-next/ExpansionPanel';
import ListSubheader from 'material-ui-next/List/ListSubheader';
import {ChevronDown} from 'mdi-material-ui';
import Grid from 'material-ui-next/Grid';
const OTHERPAGES = require('data/pages.js');
const systemMenuData = OTHERPAGES['systemMenuPagesItems'];

class SystemMenu extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            expanded: null,
        };
    }

    handleChange = panel => (event, expanded) => {
        this.setState({
            open: false,
            expanded: expanded ? panel : false,
        });
    };

    render() {
        const { expanded, open } = this.state;
        return (
            <div>
                <Grid
                    container>
                    <Grid item xs={12} style={{padding: 0}}>
                        <ListSubheader component="div">MENU ITEMS</ListSubheader>
                    </Grid>
                </Grid>
                <Grid
                    container>
                    <Grid item xs={12}>
                        <ExpansionPanel
                            expanded={expanded === 'panel1'}
                            onChange={this.handleChange('panel1')}>
                            <ExpansionPanelSummary
                                expandIcon={<ChevronDown />}>
                                Players
                            </ExpansionPanelSummary>
                            <ExpansionPanelDetails>
                                <List>
                                    <ListItem
                                        button
                                        component="a"
                                        href="/app/page1">
                                        <ListItemText primary="Page 1" />
                                    </ListItem>
                                    <ListItem
                                        button
                                        component="a"
                                        href="/app/page2">                                          
                                        <ListItemText primary="Page 2" />
                                    </ListItem>
                                    <ListItem
                                        button
                                        component="a"
                                        href="/app/page3">                                          
                                        <ListItemText primary="Page 3" />
                                    </ListItem>
                                </List>
                            </ExpansionPanelDetails>
                        </ExpansionPanel>
                    </Grid>
                </Grid>
            </div>
        );
    }
}

export default withStyles(styles)(SystemMenu);
这需要持久变量和
handleOpen()
函数来保持抽屉打开,直到我单击具有
handleClose()函数的列表。我的抽屉现在看起来像这样

<Drawer
    variant="persistent"
    elevation={16}
    anchor="right"
    open={this.state.open}
    onClick={() => { this.handleOpen(); }}>
    ...
       My System Menu code in here, not too happy about this part. :(
    ...
</Drawer>

这是一个不错的方法,但我更希望将SystemMenu代码放在另一个文件中并导入到该文件中,然后使用道具从SystemMenu.js文件中操作Menu.js文件中的关闭函数。如果其他人想继续帮助我,我将不胜感激。

假设您的抽屉位于类组件中,您将执行类似操作,从子组件关闭它

class MyComponent extends React.Component {
    constructor(props){
        super(props)
        this.state = {
            open: false,
        }
    }

    closeDrawer = () => this.setState({ open: false })

    render() {            
        return (
            <Drawer
                elevation={16}
                anchor="right"
                open={this.state.open}
                onKeyDown={this.closeDrawer}
            >
                <SystemMenu 
                    closeDrawer={this.closeDrawer}
                />
            </Drawer>
        )
    }
}
在中,他们将所有列表项包装在一个div中,该div用于处理关闭抽屉的操作:


{侧列表}
在此代码中,
toggleDrawer
是一个函数,用于设置抽屉的
open
属性所使用的状态。因此,当按下一个键或在列表的一个子项中发生单击时,事件会出现在这些处理程序中(只要不使用
event.stopPropagation()
),并且状态会更改

在代码中,您不希望扩展器单击关闭抽屉,因此必须以不同的方式处理这些事件

您可以将
onClick
处理程序添加到列表中:


{/*在此关闭抽屉*/}>
然后,当单击ListItems时,事件将冒泡到列表的处理程序,该处理程序设置状态,关闭抽屉

根据代码的结构,您可能需要修改抽屉的实现,以便将函数传递给
SystemMenu
组件,以便其列表上的单击处理程序可以设置其父级的状态,因为
this.setState
会影响
this
的状态,this
是该组件的当前实例。它不会设置抽屉的状态

更新:

<Drawer
    variant="persistent" //I tried "temporary", and "permanent" as well
    elevation={16}
    anchor="right"
    open={this.state.open}
    // onClick={(open) => this.setState({ open: false })}
    // onKeyDown={(open) => this.setState({ open: false })}>
    <SystemMenu />
</Drawer>
import React from 'react';
import { withStyles } from 'material-ui-next/styles';
import List, { ListItem, ListItemText } from 'material-ui-next/List';
import ExpansionPanel, { ExpansionPanelDetails, ExpansionPanelSummary } from 'material-ui-next/ExpansionPanel';
import ListSubheader from 'material-ui-next/List/ListSubheader';
import {ChevronDown} from 'mdi-material-ui';
import Grid from 'material-ui-next/Grid';
const OTHERPAGES = require('data/pages.js');
const systemMenuData = OTHERPAGES['systemMenuPagesItems'];

class SystemMenu extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            expanded: null,
        };
    }

    handleChange = panel => (event, expanded) => {
        this.setState({
            open: false,
            expanded: expanded ? panel : false,
        });
    };

    render() {
        const { expanded, open } = this.state;
        return (
            <div>
                <Grid
                    container>
                    <Grid item xs={12} style={{padding: 0}}>
                        <ListSubheader component="div">MENU ITEMS</ListSubheader>
                    </Grid>
                </Grid>
                <Grid
                    container>
                    <Grid item xs={12}>
                        <ExpansionPanel
                            expanded={expanded === 'panel1'}
                            onChange={this.handleChange('panel1')}>
                            <ExpansionPanelSummary
                                expandIcon={<ChevronDown />}>
                                Players
                            </ExpansionPanelSummary>
                            <ExpansionPanelDetails>
                                <List>
                                    <ListItem
                                        button
                                        component="a"
                                        href="/app/page1">
                                        <ListItemText primary="Page 1" />
                                    </ListItem>
                                    <ListItem
                                        button
                                        component="a"
                                        href="/app/page2">                                          
                                        <ListItemText primary="Page 2" />
                                    </ListItem>
                                    <ListItem
                                        button
                                        component="a"
                                        href="/app/page3">                                          
                                        <ListItemText primary="Page 3" />
                                    </ListItem>
                                </List>
                            </ExpansionPanelDetails>
                        </ExpansionPanel>
                    </Grid>
                </Grid>
            </div>
        );
    }
}

export default withStyles(styles)(SystemMenu);
根据你的评论,我添加了这一点

在系统菜单组件中: -接受名为
closeDrawer
的道具。 -使用props中的此函数作为列表上的
onClick
处理程序

  • 在菜单组件中:
  • 添加一个函数来关闭抽屉,现在我们称它为
    closeDrawer
  • 呈现系统菜单时,将此.closeDrawer传递为“closeDrawer”


这是从SystemMenu(子菜单)中更改父组件菜单的本地状态的一种方法。

通过PaperProps将关闭处理程序放置在MuiPaper上:

const handleClose = () => console.log('closing drawer');

const MyDrawer = () => <Drawer PaperProps={{onClick: handleClose}} />
consthandleclose=()=>console.log('closing drawer');
常量MyDrawer=()=>

这将在单击抽屉内的任何位置时关闭抽屉。

对不起,我忘了提到系统菜单在一个单独的文件中,我正在导入包含抽屉的文件中。它无法识别ToggleDrawer函数,因为它是在一个单独的文件中声明的。以及它在SystemMenu文件中也没有声明的Drawer组件,但它是包含该Drawer的Menu.js。这就是为什么我认为道具是正确的方法。这不是道具应该做的吗?操作文件外部存在的函数?在它的父级?我想出了一个方法让它工作,但我必须在菜单文件中有系统菜单代码,这样我才能访问导入和功能。请参阅我的编辑+谢谢你的工作,因为你让我的齿轮转动。然而,我的问题仍然存在。我更希望能够从另一个文件中的子代码操纵抽屉。我知道它们位于不同的文件中,这就是为什么我写道,您需要从定义抽屉的位置向SystemMenu传递一个函数。在呈现抽屉的类中创建一个
closeDrawer
函数,并在SystemMenu组件中显示一个可以接受它的道具。然后在SystemMenu组件中,将其用作列表的单击处理程序。@LOTUSMS在我拼出来的地方看到更新的答案。
const handleClose = () => console.log('closing drawer');

const MyDrawer = () => <Drawer PaperProps={{onClick: handleClose}} />