我怎样才能从 react beautiful dnd 中获得组合来处理我的项目?

Posted

技术标签:

【中文标题】我怎样才能从 react beautiful dnd 中获得组合来处理我的项目?【英文标题】:How can I get combining from react beautiful dnd to work on my items? 【发布时间】:2021-01-15 21:59:41 【问题描述】:

我正在使用 react beautiful dnd 并创建了 3 个包含列表项的列。我想添加组合项目的功能。我已经阅读了文档,但似乎仍然无法弄清楚它为什么不起作用。

问题似乎出在 onDragEnd,它可以在文档中找到 result.combine (combine),但它似乎不是 true它到达 if 语句。我忽略了什么吗?有人可以向我解释发生了什么,为什么它不起作用?

提前谢谢你!

我使用过的资源:

https://react-beautiful-dnd.netlify.app/?path=/story/board--with-combining https://github.com/atlassian/react-beautiful-dnd/blob/master/docs/guides/combining.md https://egghead.io/lessons/react-move-items-between-columns-with-react-beautiful-dnd-using-ondragend (尽管没有任何组合!)

我的数据:

const initialData = 
  tasks: 
    'task-1':  id: 'task-1', content: 'task-1' ,
    'task-2':  id: 'task-2', content: 'task-2' ,
    'task-3':  id: 'task-3', content: 'task-3' ,
  ,
  columns: 
    'column-1': 
      id: 'column-1',
      title: 'column-1',
      taskIds: ['task-1', 'task-2'],
    ,
    'column-2': 
      id: 'column-2',
      title: 'column-2',
      taskIds: [],
    ,
    'column-3': 
      id: 'column-3',
      title: 'column-3',
      taskIds: ['task-3'],
    ,
  ,
  columnOrder: ['column-1', 'column-2', 'column-3'],
;

export default initialData;

使用 onDragEnd 索引文件

const onDragEnd = result => 
    const  destination, source, draggableId, combine  = result;

    //console.log(`drag: $combine.draggableId drop: $combine.droppableId`);

    if (!destination) 
      return; // not dropped in a known destination
    
    if (destination.draggableId === source.droppableId && destination.index === source.index) 
      return; // dropped in same location
    

    const start = state.columns[source.droppableId]; //get selected column
    const finish = state.columns[destination.droppableId]; //get new selected column

    if (combine)  

      //console.log(`drag: $combine.draggableId drop: $combine.droppableId`); 

      const combineTaskIds = Array.from(start.taskIds); 
      combineTaskIds.splice(source.index, 1); 
      const newColumn = 
        ...start,
        taskIds: combineTaskIds,
      ; 

      setState(prevState => ( ...prevState, columns:  ...prevState.columns, [newColumn.id]: newColumn  ));
    

    if (start === finish)  //move in same column
      const newTaskIds = Array.from(start.taskIds);
      newTaskIds.splice(source.index, 1); 
      newTaskIds.splice(destination.index, 0, draggableId); 

      const newColumn = 
        ...start,
        taskIds: newTaskIds,
      ; // create new column with new tasks

      setState(prevState => ( ...prevState, columns:  ...prevState.columns, [newColumn.id]: newColumn  ));
    

    if (start !== finish)  
      const startTaskIds = Array.from(start.taskIds);
      startTaskIds.splice(source.index, 1); 
      const newStart = 
        ...start,
        taskIds: startTaskIds,
      ;

      const finishTaskIds = Array.from(finish.taskIds);
      finishTaskIds.splice(destination.index, 0, draggableId); 
      const newFinish = 
        ...finish,
        taskIds: finishTaskIds,
      ;

      setState(prevState => ( ...prevState, columns:  ...prevState.columns, [newStart.id]: newStart, [newFinish.id]: newFinish  ));
    
  

return <DragDropContext onDragEnd=onDragEnd >
    <Container>
      
        state.columnOrder.map(columnId => 
          const column = state.columns[columnId];
          const tasks = column.taskIds.map(taskId => state.tasks[taskId]);

          return <Column key=column.id column=column tasks=tasks />;
        )
      
    </Container>
  </DragDropContext >

可放置的列 (将 isCombineEnabled 设为 true)

  <Container>
      <List dense>
        <ListItemText primary=props.column.title />
        <Droppable droppableId=props.column.id isCombineEnabled>
          (provided, snapshot) => (
            <ListItem
              ...provided.droppableProps
              innerRef=provided.innerRef
              isDraggingOver=snapshot.isDraggingOver
              button>
              props.tasks.map((task, index) => <Task key=task.id task=task index=index />)
              provided.placeholder
            </ListItem>
          )
        </Droppable>
      </List>
    </Container>

可拖动的任务项

<Draggable draggableId=props.task.id index=props.index>
      (provided, snapshot) => (
        <Container
          ...provided.draggableProps
          ...provided.dragHandleProps
          innerRef=provided.innerRef
          isDragging=snapshot.isDragging
        >
          props.task.content
        </Container>
      )
    </Draggable>

【问题讨论】:

【参考方案1】:

最后我已经解决了这个问题,并想分享这个,以防有人最终遇到同样的问题。

问题确实出在 onDragEnd 中,然后才到达 combine 的条件。 const finish 需要根据使用情况进行更改,因为它会有一个或另一个。合并或目的地。

    const onDragEnd = result => 
    const  destination, source, draggableId, combine  = result;

  if (!combine && !destination) 
      return; // not dropped in a known destination
    
    if (!combine && destination.draggableId === source.droppableId && destination.index === source.index) 
      return; // dropped in same location
    

    const start = state.columns[source.droppableId]; //get selected column
    const finish = combine ? state.columns[combine.droppableId] : state.columns[destination.droppableId]; //get new selected column

    if (combine) 
      //just removing the dragging item
      const combineTaskIds = Array.from(start.taskIds); //create new array with current columns taskids 
      combineTaskIds.splice(source.index, 1); // from this index we want to remove 1 item
      const newColumn = 
        ...start,
        taskIds: combineTaskIds,
      ; // create new column with new tasks

      setState(prevState => ( ...prevState, columns:  ...prevState.columns, [newColumn.id]: newColumn  ));
    

    if (start === finish)  //move in same column
      const newTaskIds = Array.from(start.taskIds);
      newTaskIds.splice(source.index, 1); // from this index we want to remove 1 item
      newTaskIds.splice(destination.index, 0, draggableId); // from this index we want to add the draggable item

      const newColumn = 
        ...start,
        taskIds: newTaskIds,
      ; // create new column with new tasks

      setState(prevState => ( ...prevState, columns:  ...prevState.columns, [newColumn.id]: newColumn  ));
    

    if (start !== finish)  //move to different column
      const startTaskIds = Array.from(start.taskIds);
      startTaskIds.splice(source.index, 1); //remove item from index
      const newStart = 
        ...start,
        taskIds: startTaskIds,
      ;

      const finishTaskIds = Array.from(finish.taskIds);
      finishTaskIds.splice(destination.index, 0, draggableId); // add draggable to index
      const newFinish = 
        ...finish,
        taskIds: finishTaskIds,
      ;

      setState(prevState => ( ...prevState, columns:  ...prevState.columns, [newStart.id]: newStart, [newFinish.id]: newFinish  ));
    
  

欢迎对我的回答进行任何补充或更正。

【讨论】:

以上是关于我怎样才能从 react beautiful dnd 中获得组合来处理我的项目?的主要内容,如果未能解决你的问题,请参考以下文章

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

Optimistic React Apollo ui lag with React Beautiful Drag and Drop

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

React:我怎样才能让这个 React 组件写得更好更高效?

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

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