如何在ag-grid react中实现非托管多行拖动?
How to implement unmanaged multi-row dragging in ag-grid react?
我一直在尝试解决如何在使用非托管行拖动的同时在 ag-grid 中实现多行拖动。到目前为止,我的单行拖动工作正常,但在拖动多行时似乎无法访问行节点列表。
在我的 onRowDragEnter
、onRowDragMove
等函数中获得的 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>
);
};
我一直在尝试解决如何在使用非托管行拖动的同时在 ag-grid 中实现多行拖动。到目前为止,我的单行拖动工作正常,但在拖动多行时似乎无法访问行节点列表。
在我的 onRowDragEnter
、onRowDragMove
等函数中获得的 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>
);
};