如何使React-Bootstrap模态框可拖动?

6
我尝试过让它正常工作,但出现了以下情况:
  1. 使用react-draggable npm包,我能够使内容可拖动和放置。但是整个对话框的背景保持不变,之后看起来就有问题了。
我还在网上找到了这个链接
import { Modal } from 'react-bootstrap'
import ModalDialog from 'react-bootstrap/lib/ModalDialog'
import Draggable from 'react-draggable'

class DraggableModalDialog extends React.Component {
    render() {
        return <Draggable handle=".modal-title"><ModalDialog 
{...this.props} /></Draggable>
    }
}

// enforceForce=false causes recursion exception otherwise....
export default ({titleIconClass, modalClass, children, title,...props}) =>
<Modal dialogComponent={DraggableModalDialog} show={true} enforceFocus={false} backdrop="static" {...props}>
    <Modal.Header closeButton>
        <Modal.Title>
            {title}
        </Modal.Title>
    </Modal.Header>
    <Modal.Body>
        {children}
    </Modal.Body>
</Modal>

我从搜索中得到了这段代码,但实际上我并不能让它正常工作。
特别是这一部分,
<ModalDialog {...this.props} />

我不明白为什么要传递props以及传递什么类型的props。

还有,

<Modal dialogComponent={DraggableModalDialog} show={true} enforceFocus={false} backdrop="static" {...props}>

<------ {...props} 这是什么意思?它似乎并没有将 props 传递给 Modal,那它的目的是什么?它是否与下文相关?

"<ModalDialog {...this.props} />"

有没有人能给我一些提示,如何使这两个问题在这种情况下有效?

谢谢!


你阅读了整个要点吗?那里的最后一条评论是你应该import Draggable from 'react-draggable'; - Dekel
是的,我已经安装并导入了它。 - user6605865
因此,请使用相关的更新代码更新问题并添加您收到的错误。 - Dekel
T___T.. 我没有收到任何错误信息。它什么也没显示出来。我尝试使用 console.log 进行输出以查看它是否有效,但是它并没有。我对这段我从网上得到的代码感到非常困惑,很难理解。 - user6605865
我明白了。让我试一试。非常感谢您的指导。 - user6605865
显示剩余7条评论
3个回答

6

对于那些仍在苦苦挣扎使用最新版本的react-bootstrap(在撰写本文时,我的版本是1.0.0-beta.5),这里是修改后的版本(https://gist.github.com/burgalon/870a68de68c5ed15c416fab63589d503)。

import React, { Component } from "react";
import Modal from "react-bootstrap/Modal";
import Draggable from 'react-draggable';
import ModalDialog from 'react-bootstrap/ModalDialog';

class DraggableModalDialog extends React.Component {
    render() {
        return <Draggable handle=".modal-title"><ModalDialog {...this.props} /> 
   </Draggable>
    }
}

export default class BSModal extends Component {

render() {
    return (
        <Modal
                dialogAs={DraggableModalDialog} 
                show={this.props.show} 
                onHide={this.props.close}>
            <Modal.Header>
                <Modal.Title>{this.props.title}</Modal.Title>
            </Modal.Header>
            <Modal.Body>
                {this.props.children}
            </Modal.Body>
            <Modal.Footer >
            </Modal.Footer>
        </Modal>
    );
}
}

有没有办法使整个标题栏可拖动,但仍然具有退出按钮功能,因为它包含在标题栏中? - Young Scooter
@YoungScooter 我猜,它将基于 .modal-title 类,因此快速的一种方法是向 .modal-title 添加 width:100% - Hung Cao

1

我收到了一个警告:在StrictMode下,findDOMNode已经被弃用

我通过使用nodeRef代替handle来解决了这个问题。我的函数组件/TypeScript DraggableModalDialog看起来像这样:

/* eslint-disable react/jsx-props-no-spreading */
import React, { RefObject } from 'react';
import Draggable from 'react-draggable';
import ModalDialog, { ModalDialogProps } from 'react-bootstrap/ModalDialog';

export interface DraggableModalDialogProps extends ModalDialogProps {
  nodeRef?: RefObject<HTMLElement>;
}

function DraggableModalDialog({ nodeRef, ...props }: DraggableModalDialogProps) {
  return (
    <Draggable nodeRef={nodeRef}>
      <ModalDialog {...props} />
    </Draggable>
  );
}

export default DraggableModalDialog;

模态组件类似于以下内容(这里简化了一下):

import React, { useRef } from 'react';
import { Modal, Button } from 'react-bootstrap';
import DraggableModalDialog from 'components/DraggableModalDialog';

export interface MyModalProps {
  visible: boolean;
  onClose: () => void;
}

function MyModal({ visible, onClose }: MyModalProps) {
  const nodeRef = useRef<HTMLDivElement>(null);
  return (
    <Modal
      nodeRef={nodeRef}
      dialogAs={DraggableModalDialog}
      show={visible}
      centered
      size="lg"
      backdrop="static"
      onHide={onClose}
    >
      <Modal.Header ref={nodeRef}>
        <Modal.Title>TITLE</Modal.Title>
      </Modal.Header>
      <Modal.Body>BODY</Modal.Body>
      <Modal.Footer>
        <Button variant="primary" onClick={onClose}>CLOSE</Button>
      </Modal.Footer>
    </Modal>
  );
}

export default MyModal;

0

我认为这个解决方案更简单,你可以使用整个模态框标题来拖动模态框。

import { Modal, ModalHeader, ModalBody } from "reactstrap";
import Draggable from "react-draggable";

...

<Draggable handle=".handle">
  <Modal size="lg" toggle={function noRefCheck(){}}>
    <ModalHeader toggle={function noRefCheck(){}} className="handle">
      Modal Title
    </ModalHeader>
    <ModalBody>
      Modal Body
    </ModalBody>
  </Modal>
</Draggable>

不确定这是否有效,因为Modal与ModalDialog不同。至少我无法拖动整个Modal。但是我在我的DraggableModalDialog中使用了.modal-header作为手柄,因此整个标题可以用作手柄。 - SinunHenkka
@SinunHenkka,你说的ModalDialog是什么意思?Reactstrap只有一个名为“Modal”的组件。 - ikreb
非常抱歉,我太匆忙了,没有注意到您的解决方案不适用于react-bootstrap。如果react-bootstrap不是必需的,我认为您的reactstrap解决方案更简单。 - SinunHenkka

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接