如何在ag-grid react中实现非托管多行拖动?

How to implement unmanaged multi-row dragging in ag-grid react?

我一直在尝试解决如何在使用非托管行拖动的同时在 ag-grid 中实现多行拖动。到目前为止,我的单行拖动工作正常,但在拖动多行时似乎无法访问行节点列表。

在我的 onRowDragEnteronRowDragMove 等函数中获得的 RowDragEvent 事件中,即使选择多个并将它们拖动到 RowDragEvent.nodes 值是空的,当它should be a list of all moving nodes。因此,如果有意义的话,它在屏幕上显示为“持有”多个但只有“移动”一个。请参阅下文了解我的意思。

(它只拖了 Test 23 而它应该拖其他两个)

这可能与我的 <AgGridReact ... /> 组件没有使用正确的 props/settings 有关吗?或者此功能当前不适用于非托管拖动?

根据上下文,我的网格已分组,并且我在下面添加了一些代码

  // https://www.ag-grid.com/react-data-grid/row-dragging/#example-dragging-with-row-groups
  const onRowDragMove = (event: RowDragEvent) => {
    // here's where I want to use event.nodes, but it's always undefined
    !event.node.group &&
      // extra functionality here to save data to our backend
      rowDragUpdateFn(event, (movingData, changedParams) => {
        gridAPI.applyTransaction({
          update: [movingData],
        });
        gridAPI.clearFocusedCell();
      });
  };
  <AgGridReact
  ...
    onRowDragEnter={onRowDragEnter}
    onRowDragEnd={onRowDragEnd}
    onRowDragMove={onRowDragMove}
    rowDragEntireRow
    rowDragMultiRow
    rowSelection={"multiple"}
  ...
  />

更新:2022 年 3 月 1 日

在 Github 上为此创建了一个问题: https://github.com/ag-grid/ag-grid/issues/4932


这似乎是 Ag-grid 中的错误,在 Ag-grid 社区 27.0.1 中仍然存在问题。这是一个解决方法,它通过检查当前选择来确定正在拖动哪些行。在此示例中,我正在计算 onRowDragEnter 中的拖动行集,因为您需要 onRowDragMove 中的此信息。但是,如果您只需要知道在拖动结束时移动了哪些行,这也可以在 onRowDragEnd 中完成。这简化了代码,因为我们甚至不需要 ref.

const Workaround: React.FC = () => {
  // Keeps track of dragged rows across all the row drag events.
  // useRef instead of useState to avoid re-rendering.
  const draggedNodes = useRef<RowNode[] | null>();

  const onRowDragEnter = (event: RowDragEvent) => {
    // Determine list of dragged nodes whenever drag starts or re-enters the grid.
    // We have to do it in both cases because we may never get drag end event (if
    // drag ends outside the grid).

    // There's probably a way to differentiate drag start and drag re-enter, but
    // it doesn't seem worth the effort unless the app can have very large numbers
    // of rows selected at the same time.

    // Dragged node
    const { node } = event;

    // Nodes currently selected in the grid
    const selectedNodes = event.api.getSelectedNodes();

    // If user is dragging one of the selected rows, then they are dragging all the selected rows.
    // I am using checkbox selection, so some rows may be selected, but user is free to drag
    // one of the rows that are not selected. So we check if the dragged node is part of
    // current selection to determine if user is dragging selected rows or a different row.
    if (selectedNodes.length > 1 && selectedNodes.includes(node)) {
      // Dragging all selected rows
      draggedNodes.current = selectedNodes;
    } else {
      // Dragging a single row
      draggedNodes.current = [node];
    }
  };

  const onRowDragMove = (event: RowDragEvent) => {
    // Use draggedNodes.current instead of event.nodes
  };

  const onRowDragLeave = (event: RowDragEvent) => {
    // Clear ref on leave in case drag ends outside the grid.
    draggedNodes.current = null;
  };

  const onRowDragEnd = (event: RowDragEvent) => {
    if (draggedNodes.current) {
      // Do something with draggedNodes.current, then clear ref.
      console.log(draggedNodes.current);
      draggedNodes.current = null;
    }
  };

  return (
    <div>
      <AgGridReact
        onRowDragEnter={onRowDragEnter}
        onRowDragMove={onRowDragMove}
        onRowDragLeave={onRowDragLeave}
        onRowDragEnd={onRowDragEnd}
        rowDragMultiRow
      />
    </div>
  );
};