首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >MaterialUI-孩子们点击下一个紧凑型抽屉

MaterialUI-孩子们点击下一个紧凑型抽屉
EN

Stack Overflow用户
提问于 2018-03-02 14:33:19
回答 3查看 7.9K关注 0票数 3

我正在运行MaterialUI-下一步,我尝试了抽屉的所有变体,但当抽屉中的项目被单击时,我无法关闭它。我知道临时变体允许我这样做,但当点击任何东西时,它就会关闭。我需要它关闭只有当一个ListItem被点击。

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

我的代码是非常基本的和普通的,实际上是来自材料界面-下一个抽屉的完全的演示。他们也有一个操场来测试代码。但是无论如何,这是我的一些相关代码

我的抽屉:

代码语言:javascript
复制
<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>

我的内容存储在SystemMenu:

代码语言:javascript
复制
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);

我在其他帖子中看到,你可以用道具把onKeyDown={(open) => this.setState({ open: false })}传递给它的孩子。但我是新的反应,并有一些问题的概念。

基本上,我需要让onKeyDown为ListItems工作,而不是实际的抽屉。我可能需要也可能不需要将我的抽屉变量更改为onKeyDown属性的临时变量。不太确定。

(请记住,上面的链接提供了一个测试代码的操场。比我想要构建一个jFiddle来做出反应要好得多)

编辑

我想出了一种不同的方法,但不是我最喜欢的。

通过将SystemMenu中的内容移动到Menu.js文件(在这里,我的抽屉导入、函数和状态是动态的),我能够创建一个带有超时的handleClose函数,从而关闭它。这是一项功能:

代码语言:javascript
复制
handleClose = () => {
    if (!this.state.open) {
        return;
    }
    this.timeout = setTimeout(() => {
        this.setState({ open: false });
        this.setState({ expanded: null });
    });
};

这需要持久变体和handleOpen()函数来保持抽屉打开,直到我单击具有handleClose()函数的列表为止。我的抽屉现在看起来像这样

代码语言:javascript
复制
<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>

接下来,在包含扩展面板和列表的系统菜单代码中,我将handleClose()函数添加到列表中,它导航并关闭抽屉和展开面板。如下所示:

代码语言:javascript
复制
<List 
    className="quickpanel-navigation"
    onClick={() => { this.handleClose(); }}>
    .... ListItems code here ....
</List>

这是一个Ok方法,但我更希望在另一个文件中使用SystemMenu代码,并将其导入到这个文件中,并使用道具从SystemMenu.js文件中操作Menu.js文件中的关闭函数。如果还有人想继续帮我,我会很感激的。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2018-03-02 15:03:08

演示中,它们将所有的ListItems包装在一个打开抽屉的div中:

代码语言:javascript
复制
<div
  tabIndex={0}
  role="button"
  onClick={this.toggleDrawer('left', false)}
  onKeyDown={this.toggleDrawer('left', false)}
>
  {sideList}
</div>

在这段代码中,toggleDrawer是一个函数,它设置抽屉的open支柱所使用的状态。因此,当一个键被按下或在列表的一个子列表中发生单击时,事件就会泡状到这些处理程序(只要不使用event.stopPropagation() )并改变状态。

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

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

代码语言:javascript
复制
<ExpansionPanelDetails>
    <List onClick={ () => { /* close the drawer here */ } }>
        <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>

然后,当单击ListItems时,事件将冒泡到列表的处理程序,该处理程序设置状态,关闭抽屉。

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

更新:

根据你的评论,我加入了这一点。

在SystemMenu组件中:-接受一个名为closeDrawer的道具。-将此函数从道具中用作列表中的onClick处理程序

  • 在菜单组件中:
  • 添加一个函数来关闭抽屉,让我们现在称它为closeDrawer
  • 在呈现SystemMenu时,将this.closeDrawer传递为“`closeDrawer”
代码语言:javascript
复制
     <SystemMenu closeDrawer={this.closeDrawer} ...>

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

票数 7
EN

Stack Overflow用户

发布于 2019-11-01 13:34:50

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

代码语言:javascript
复制
const handleClose = () => console.log('closing drawer');

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

这将关闭当点击抽屉内任何地方的抽屉。

票数 4
EN

Stack Overflow用户

发布于 2018-03-02 15:02:09

假设您的抽屉位于类组件中,您可以这样做,以便从子组件中关闭它。

代码语言:javascript
复制
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>
        )
    }
}

然后您可以从this.props.closeDrawer内部访问SystemMenu。听起来像是要为列表项添加到onClick处理程序中:

代码语言:javascript
复制
<ListItem
    button
    component="a"
    href="/app/page1"
    onClick={this.props.closeDrawer}
>
    <ListItemText primary="Page 1" />
</ListItem>
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49071231

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档