如果所有三个容器都是使用一种方法呈现的,我怎样才能在 Dragula 中使所有三个容器都可拖动?使用 React js 和 Dragula(不是 react-dragula)

Posted

技术标签:

【中文标题】如果所有三个容器都是使用一种方法呈现的,我怎样才能在 Dragula 中使所有三个容器都可拖动?使用 React js 和 Dragula(不是 react-dragula)【英文标题】:How can I make all three containers draggable in Dragula, if all three are rendered using a method? Using React js and Dragula (not react-dragula) 【发布时间】:2020-09-14 13:34:20 【问题描述】:

在这里反应初学者。所以基本上,我想要 3 列包含可以拖动以在同一列内重新排序或移动到不同列的元素。它的代码分为 2 个类,以分隔每列中应包含哪些相关元素。

这是定义每列结构的类 (Swimlane.js) 的代码:

import React from 'react';
import Card from './Card';
import Dragula from 'dragula';
import './Swimlane.css';



export default class Swimlane extends React.Component 

  render() 

  const dragulaDecorator = (componentBackingInstance) =>  
      if (componentBackingInstance) 
        let options = 
          moves: function (el, source, handle, sibling) 
            return true;
          ,
          accepts: function (el, target, source, sibling) 
            return true;
          ,
          direction: 'vertical',
          copy: false,           
          copySortSource: false,
          revertOnSpill: false,              
          removeOnSpill: false,   
          mirrorContainer: document.body,   
          ignoreInputTextSelection: true,
        

        console.log('componentBackingInstance: ');
        console.log(componentBackingInstance);
        Dragula([componentBackingInstance]);
      
    ;

    const cards = this.props.clients.map(client => 
      return (
        <Card
          key=client.id
          id=client.id
          name=client.name
          description=client.description
          status=client.status
        />
      );
    )
    return (
      <div className="Swimlane-column" class="Swimlane Column">
        <div className="Swimlane-title">this.props.name</div>
        <div className="Swimlane-dragColumn" ref=dragulaDecorator> /* this is the column that contains all my elements, and the one I want to make my container */
          cards
        </div>
      </div>);
  



在下一个类 Board.js 中调用 Swimlane.js 来实际渲染所有组件。

import React from 'react';
import Dragula from 'dragula';
import 'dragula/dist/dragula.css';
import Swimlane from './Swimlane';
import './Board.css';

export default class Board extends React.Component 
  constructor(props) 
    super(props);
    const clients = this.getClients();

    this.state = 
      clients: 
        backlog: clients.filter(client => !client.status || client.status === 'backlog'),
        inProgress: clients.filter(client => client.status && client.status === 'in-progress'),
        complete: clients.filter(client => client.status && client.status === 'complete'),
      
    
    this.swimlanes = 
      backlog: React.createRef(),
      inProgress: React.createRef(),
      complete: React.createRef(),
    



  

  getClients() 
    return [
      // [id, name, description, status]
      ['1','Name 1','Description 1', 'backlog'],
      ['2','Name 2','Description 2', 'in-progress'],
      ['3','Name 3','Description 3', 'backlog'],
      ['4','Name 4','Description 4', 'complete'],
    ].map(companyDetails => (
      id: companyDetails[0],
      name: companyDetails[1],
      description: companyDetails[2],
      status: companyDetails[3],
    ));
  
  renderSwimlane(name, clients, ref) 
    return (
      <Swimlane name=name clients=clients dragulaRef=ref/>
    );
  

  render() 

    return ( 
      <div className="Board">
        <div className="container-fluid">
          <div className="row"> 
            <div className="col-md-4">
              this.renderSwimlane('Backlog', this.state.clients.backlog, this.swimlanes.backlog)
              </div>
            <div className="col-md-4">
              this.renderSwimlane('In Progress', this.state.clients.inProgress, this.swimlanes.inProgress)
              </div>
            <div className="col-md-4">
              this.renderSwimlane('Complete', this.state.clients.complete, this.swimlanes.complete)
              </div>  
          </div>
        </div>
      </div>
    );
  

因此,getClients() 方法用于制作 'state' 道具和 'swimlanes' 道具,renderSwimlane() 方法使用它们来渲染 3 列所有相关信息。

现在,如果我运行这段代码,三个“Swimlane-dragColumn”div 中的所有可拖动元素都可以在它们自己的容器中排序,但不能移动到其他容器中。另外,请忽略导入 Card.js 的声明,它是一个基本上显示每个可拖动元素应该是什么样子的类(颜色等)。

在这里(how to move a dragula draggable element to another div in react-dragula?)提出了类似的问题,但我无法理解答案的含义(由于缺乏声誉,我无法发表评论)。如何获得所有三个具有类名“Swimlane-dragColumn”的列,这些列将被呈现为可行的容器?我已经能够发现我应该在某处使用“推送”功能,但我不知道如何实现它。

谢谢

【问题讨论】:

【参考方案1】:
  componentDidMount()
    Dragula(Array.from(document.getElementsByClassName('Swimlane-dragColumn')))
    
  componentDidUpdate()
    Dragula(Array.from(document.getElementsByClassName('Swimlane-dragColumn')))
    

我相信这是夏尔巴人内部的,任务与反应钩子有关,试试这个并继续工作

【讨论】:

【参考方案2】:

如果您愿意添加一个库,我在这里写了这个:https://github.com/jpribyl/react-hook-dragula

它提供了强类型,并允许您在react 环境中轻松使用dragula。它只会给你的包增加 22kb(假设你已经有了 react + dragula)

在我看来,您只需要多个容器即可达到您想要的结果。这个演示的第一个例子应该是类似的:https://johnpribyl.com/react-hook-dragula/

此处提供代码:https://github.com/jpribyl/react-hook-dragula/blob/main/example/src/examples/TwoContainerExample.tsx

如果有什么不清楚的地方请告诉我!我相信您的解决方案是这样的:

<Dragula className="row">
  <DragulaContainer className="col">
    <Draggable>
      column 1
    </Draggable>
  </DragulaContainer>

  <DragulaContainer className="col">
    <Draggable>
      column 2
    </Draggable>
  </DragulaContainer>

  <DragulaContainer className="col">
    <Draggable>
      column 3
    </Draggable>
  </DragulaContainer>
</Dragula>

【讨论】:

以上是关于如果所有三个容器都是使用一种方法呈现的,我怎样才能在 Dragula 中使所有三个容器都可拖动?使用 React js 和 Dragula(不是 react-dragula)的主要内容,如果未能解决你的问题,请参考以下文章

我怎样才能呈现一个模态视图控制器,并带有默认的关闭动画?

PyQt5 将线条延伸到正在绘制的图像之外。我怎样才能防止这种情况发生?

横拍制作的视频,画面为啥是狭窄的?怎样才能显示出宽频效果?

我怎样才能获得将在其中绘制子字符串的绑定矩形?

如何渲染组件取决于角色

我怎样才能圆容器表视图的角落?