使用 react-beautiful-dnd 嵌套拖放

Posted

技术标签:

【中文标题】使用 react-beautiful-dnd 嵌套拖放【英文标题】:Nested Drag and Drop with react-beautiful-dnd 【发布时间】:2019-03-19 17:17:44 【问题描述】:

我正在使用react-beautiful-dnd 创建垂直嵌套拖放。我推荐了一些answers in github

我从沙盒中分叉并创建了一个新的用于垂直嵌套拖放的沙盒。 当我更改内部 DND 时,外部 DND 会更改不在 DND 内部的值。

代码

 onDragEnd(result) 
    // dropped outside the list
    console.log("innner drag");
    if (!result.destination) 
      return;
    

    const items = reorder(
      this.state.items,
      result.source.index,
      result.destination.index
    );

    this.setState(
      items
    );
  

DEMO代码:https://codesandbox.io/s/ozq53zmj6

【问题讨论】:

在 react-beautiful-dnd 中,所有 onDragEnd 事件都由根 DragDropContext 处理。目前,嵌套的 DragDropContexts aren't supported。在您的 ServiceCommandUnit.js 文件中,您实际上并未在任何地方使用 onDragEnd 函数。我的建议是将 ServiceCommandUnit.js 的状态提升到 index.js,并检查结果中的 droppableId 以检查每次调用 onDragEnd 时应该处理哪个“列表”。 另外,提示:“draggableID”可以是任何你想要的字符串。因此,如果您愿意,可以嵌入所有信息以将可拖动内容标识为对象,然后对其进行 JSON.stringify 并将其用作“draggableID”。这就是我目前所做的,尽管它不是那样的意图。 ^_^ 对于像我这样来自谷歌的人,请注意,彼此完全无关的DragDropContexts 完全可以。所以你可以在 DragDropContext 中有一个 DragDropContext,如果你不在它们之间拖动,那完全没问题。 【参考方案1】:

react-beautiful-dnd 目前不支持嵌套拖放,根据他们的路线图,它是低优先级项目。您需要处理外部<DragDropContext onDragEnd=this.handleDragEnd> 上的所有内容。默认情况下它不会在result 对象中提供父信息,因此我将这些信息保存在子Droppable 组件中。如果这对您有用,请参阅下面的演示。

代码:https://codesandbox.io/s/jp4ow4r45v

编辑:请参阅下面的沙箱以获得更通用的代码 sn-p,您可以在其中跨父容器应用嵌套拖放。

代码:https://codesandbox.io/s/5v2yvpjn7n

【讨论】:

在第二个例子中,有没有办法让项目可以在级别之间拖动?就像我想将subitem1 移动到根目录下或items2 移动到items1 的子项下。或者是否有任何其他库可以实现这种 DaD 行为? 在第二个示例中,您可以重新排序单个items,您可以在item 中重新排序subItems,您可以将subItems 从一个item 拖放到另一个@987654337 @。如果我正确理解了您的问题,您希望将 subItemitem2 容器移动到 item1 容器,这是可能的。您可以在codesandbox 中试用 我正在寻找的是this functionality。虽然这个包并不理想,因为我必须通过包将我的数据转换为所需的格式,它可以满足我的需要。 是的 react-beautiful-dnd 目前不支持嵌套拖放,这就是为什么将所有逻辑移动到父级是这个库唯一的选择。你可以试试react-dnd 基于第二个示例,是否可以允许在 subitems 之间删除 item,在 items 之间删除 subitem【参考方案2】:

只需为您的外部和内部 droppable 指定类型,在拖动端您必须检查您的 droppable 的类型,并相应地重新排序。

onDragEnd = ( type, destination, source ) => 

    if (source && destination && type) 
        let parentId = source.droppableId;
        let srcIndex = source.index;
        let destIndex = destination.index;

        if (type == "Inner") 
            //method for reordering the order of the inner items
            reorderInner(parentId, srcIndex, destIndex)
        
        else if (type == "Outer") 
            //method for reordering the order of parent items
            reorderOuter(srcIndex,destIndex)
        
    

;

【讨论】:

【参考方案3】:

我也遇到过同样的问题,我也使用了 react-beautiful-dnd,但是有很多自定义更改它可以工作但并不顺利,然后我看到另一个名为 react-nestable 的包,它可以按我的需要工作.我在下面放了那个包的链接 - react-nestable npm

【讨论】:

以上是关于使用 react-beautiful-dnd 嵌套拖放的主要内容,如果未能解决你的问题,请参考以下文章

更改 react-beautiful-dnd 可拖动点击区域

Dragabbale 不会在 react-beautiful-dnd 中移动

react-beautiful-dnd:当存在多个列表时,在一行中拖动内容会从所有行中拖动相同的索引

如何让“react-beautiful-dnd”不触发“react-transition-group”动画?

React-Beautiful-dnd 元素在 2,3 次尝试后不可拖动

无法让 React-Beautiful-DND 和 React-Virtualized 一起工作