从嵌套的 material-ui 对话框中退出

Escaping from a nested material-ui dialog

当我打开一个对话框时,它会打开另一个,然后我点击退出,它会关闭两个对话框。

有没有办法让转义只关闭最上面的对话框?

我认为这不可能没有一些麻烦。在对话框渲染函数中,渲染了这个事件监听器,没有允许你覆盖它的道具。

{open &&
   <EventListener
      target="window"
      onKeyUp={this.handleKeyUp}
      onResize={this.handleResize}
   />
}

调用此方法。

handleKeyUp = (event) => {
    if (keycode(event) === 'esc') {
      this.requestClose(false);
    }
};

source

然而,您可以深入研究 node_modules/material-ui/Dialog/dialog.js 并删除或更改该代码。删除此行将阻止它在 esc 上关闭,但对所有对话框都有效。也许在那之后你可以在你自己的class中实现一个键码事件监听器来处理模式的关闭。

if ((0, _keycode2.default)(event) === 'esc') {
   _this2.requestClose(false);
}

编辑:可能的解决方案。

我创建了 2 个组件,一个 DialogContainer class 组件和一个 Dialog 功能组件。要使用它,您必须 npm install --save react-event-listener

要使其正常工作,您仍然需要从 node_modules 中删除上述代码。

当只打开一个对话框时,单击 esc 将关闭该对话框。如果打开了两个对话框,它将首先关闭 dialog2 并保持 dialog1 打开。

DialogContainer.js

import React, { Component } from 'react';
import Dialog from './Dialog';
import RaisedButton from 'material-ui/RaisedButton';
import EventListener from 'react-event-listener';

export default class DialogContainer extends Component {
  state = {
    openDialog1: false,
    openDialog2: false
  };

  handleDialog1Open = () => {
    this.setState({ openDialog1: true });
  };

  handleDialog2Open = () => {
    this.setState({ openDialog2: true });
  };

  handleDialog1Close = () => {
    this.setState({ openDialog1: false });
  };

  handleDialog2Close = () => {
    this.setState({ openDialog2: false });
  };

  handleKeyUp = (event) => {
    // 27 = esc
    if (event.keyCode === 27) {
      if (this.state.openDialog1 && this.state.openDialog2) {
        this.handleDialog2Close();
      } else {
        this.handleDialog1Close();
        this.handleDialog2Close();
      }
    }
  };

  render() {
    return (
     <div>
       {(this.state.openDialog1 || this.state.openDialog2) &&
       <EventListener
        target="window"
        onKeyUp={this.handleKeyUp}
       />}
       <RaisedButton label="Open1" onTouchTap={this.handleDialog1Open}/>
       <RaisedButton label="Open2" onTouchTap={this.handleDialog2Open}/>
       <Dialog
        openOtherDialog={this.handleDialog2Open}
        open={this.state.openDialog1}
        handleClose={this.handleDialog1Close}
        number={1}/>
       <Dialog
        open={this.state.openDialog2}
        handleClose={this.handleDialog2Close}
        number={2}/>
     </div>
    )
  }
};

Dialog.js

import React from 'react';
import Dialog from 'material-ui/Dialog';
import RaisedButton from 'material-ui/RaisedButton';

const DialogCustom = ({ open, handleClose, number, openOtherDialog}) => {
  return (
   <div>
     <Dialog
      title="Dialog"
      modal={false}
      open={open}
      onRequestClose={handleClose}
     >
       {`this is dialog ${number}`}
       {openOtherDialog &&
       <RaisedButton label="Open2" onTouchTap={openOtherDialog}/>
       }
     </Dialog>
   </div>
  );
};

export default DialogCustom;

几乎总有比同时打开两个 dialogs/modals 更好的解决方案。在我们使用 MUI 设计的 material 应用程序中,我们曾多次遇到这种情况。我们的处理方式:打开"top"对话框时关闭"underneath"对话框。然后(如果需要),您可以在关闭 "top" 对话框时重新打开 "underneath" 对话框。看起来需要做很多工作,但考虑到代码和用户体验方面的考虑,堆叠对话框变得很棘手。