Skip to content

Commit

Permalink
fix: 修复表格排序后, 编辑单元格后数据更新错误
Browse files Browse the repository at this point in the history
  • Loading branch information
wjgogogo committed Feb 7, 2024
1 parent 7d1cf9a commit e841d3d
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 48 deletions.
2 changes: 1 addition & 1 deletion packages/s2-core/src/data-set/base-data-set.ts
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ export abstract class BaseDataSet {
}

public getDisplayDataSet() {
return this.displayData;
return this.displayData || [];
}

public isEmpty() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
type DataItem,
type S2CellType,
type ViewMeta,
type RawData,
} from '@antv/s2';
import { Input } from 'antd';
import { isNil, merge, pick } from 'lodash';
Expand All @@ -27,15 +28,15 @@ import './index.less';

export interface CustomProps {
style: React.CSSProperties;
onChange: (val: string) => void;
onChange: (value: string) => void;
onSave: () => void;
value: DataItem;
spreadsheet: SpreadSheet;
cell: S2CellType | null;
}

type onChangeProps = {
onChange?: (val: any[]) => void;
type EditCellProps = {
onChange?: (val: RawData[]) => void;
onDataCellEditEnd?: (meta: ViewMeta) => void;
trigger?: number;
CustomComponent?: React.FunctionComponent<CustomProps>;
Expand All @@ -44,7 +45,7 @@ type onChangeProps = {
const EDIT_CELL_CLASS = `${S2_PREFIX_CLS}-edit-cell`;

function EditCellComponent(
props: InvokeComponentProps<{ cell: S2CellType } & onChangeProps>,
props: InvokeComponentProps<{ cell: S2CellType } & EditCellProps>,
) {
const { params, resolver } = props;
const s2 = useSpreadSheetInstance();
Expand Down Expand Up @@ -97,27 +98,30 @@ function EditCellComponent(
const inputRef = useRef<HTMLInputElement>(null);
const containerRef = useRef<HTMLDivElement>(null);

/**
* 在 Enter 确定输入后,会执行 onSave 逻辑,然后组件被销毁后,又会通过 blur 再执行一遍,这个时候 displayData 顺序已经变了,再执行获取的 rowIndex 是错误的
* 本质上,还是和 invokeComponent 中在移除 dom 节点前,没有提前 unmount 组件有关(1.x 中进行了处理,2.x 中现在只对其中一个分支处理了)
* */
const hasSaved = useRef(false);

useEffect(() => {
setTimeout(() => {
// 防止触发表格全选
if (containerRef.current) {
containerRef.current!.click();
}

if (inputRef.current) {
inputRef.current!.focus();
}
containerRef.current?.click();
// 开启 preventScroll, 防止页面有滚动条时触发滚动
inputRef.current?.focus({ preventScroll: true });
});
}, []);

const onSave = () => {
if (!cell) {
if (!cell || hasSaved.current) {
return;
}

const { rowIndex, valueField } = cell.getMeta();
const displayData = s2.dataSet.getDisplayDataSet();

s2.dataSet.originData[rowIndex][valueField] = inputVal;
displayData[rowIndex][valueField] = inputVal;
s2.render(true);

const meta = merge(cell.getMeta(), {
Expand All @@ -131,19 +135,13 @@ function EditCellComponent(
onDataCellEditEnd?.(meta);

if (onChange) {
onChange(s2.dataSet.originData);
onChange(displayData);
}

hasSaved.current = true;
resolver(true);
};

const onKeyDown: React.KeyboardEventHandler<HTMLTextAreaElement> = (e) => {
if (e.keyCode === 13) {
e.preventDefault();
onSave();
}
};

const styleProps: React.CSSProperties = {
left: cellLeft,
top: cellTop,
Expand All @@ -152,7 +150,7 @@ function EditCellComponent(
zIndex: 1000,
};

const changeValue = (val: string) => {
const onChangeValue = (val: string) => {
setInputVal(val);
};

Expand All @@ -175,7 +173,7 @@ function EditCellComponent(
spreadsheet={s2}
value={inputVal}
style={styleProps}
onChange={changeValue}
onChange={onChangeValue}
onSave={onSave}
/>
) : (
Expand All @@ -189,32 +187,34 @@ function EditCellComponent(
setInputVal(e.target.value);
}}
onBlur={onSave}
onKeyDown={onKeyDown}
onPressEnter={onSave}
/>
)}
</div>
);
}

export const EditCell = memo(({ onChange, CustomComponent }: onChangeProps) => {
const spreadsheet = useSpreadSheetInstance();
export const EditCell = memo(({ onChange, CustomComponent }: EditCellProps) => {
const s2 = useSpreadSheetInstance();

const onEditCell = useCallback(
(event: GEvent) => {
invokeComponent({
component: EditCellComponent,
params: {
cell: spreadsheet.getCell(event.target)!,
cell: s2.getCell(event.target)!,
onChange,
CustomComponent,
},
spreadsheet,
s2,
});
},
[CustomComponent, onChange, spreadsheet],
[CustomComponent, onChange, s2],
);

useS2Event(S2Event.DATA_CELL_CLICK, onEditCell, spreadsheet);
useS2Event(S2Event.DATA_CELL_CLICK, onEditCell, s2);

return null;
});

EditCell.displayName = 'EditCell';
Original file line number Diff line number Diff line change
Expand Up @@ -131,28 +131,26 @@ export const DragCopyMask = memo(({ onCopyFinished }: DragCopyProps) => {
}, 10);

const dragMouseUp = (event: MouseEvent) => {
let targetCell = getCurrentHoverCell(event);

if (!startCell) {
return;
}

if (!targetCell) {
targetCell = getCurrentHoverCell(lastHoverPoint as MouseEvent);
}
const targetCell =
getCurrentHoverCell(event) ||
getCurrentHoverCell(lastHoverPoint as MouseEvent);

const source = spreadsheet.dataSet.originData;
const displayData = spreadsheet.dataSet.getDisplayDataSet();

const selectedRange = getSelectedCellRange(startCell, targetCell!);
const { fieldValue } = startCell.getMeta();
const changedCells = selectedRange.map((item) => {
const { rowIndex, valueField } = item.getMeta();

if (
source[rowIndex] &&
typeof source[rowIndex][valueField] !== 'undefined'
displayData[rowIndex] &&
typeof displayData[rowIndex][valueField] !== 'undefined'
) {
source[rowIndex][valueField] = fieldValue;
displayData[rowIndex][valueField] = fieldValue;
}

return item;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,6 @@ export function DragCopyPoint() {
useS2Event(S2Event.ROW_CELL_CLICK, batchSelected, spreadsheet);
useS2Event(S2Event.CORNER_CELL_CLICK, batchSelected, spreadsheet);
useS2Event(S2Event.DATA_CELL_BRUSH_SELECTION, batchSelected, spreadsheet);

useS2Event(S2Event.DATA_CELL_CLICK, fixPosition, spreadsheet);

return (
Expand Down
16 changes: 9 additions & 7 deletions packages/s2-react/src/utils/invokeComponent.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { SpreadSheet } from '@antv/s2';
import React from 'react';
import { createRoot } from 'react-dom/client';
import { createRoot, type Root } from 'react-dom/client';
import { SpreadSheetContext } from '../context/SpreadSheetContext';

export type InvokeComponentProps<P> = {
Expand All @@ -12,7 +12,7 @@ export type InvokeComponentProps<P> = {
export type InvokeComponentOptions<P> = {
component: React.ComponentType<InvokeComponentProps<P>>;
params: P;
spreadsheet: SpreadSheet;
s2: SpreadSheet;
id?: string;
onCleanup?: () => void;
};
Expand All @@ -21,7 +21,7 @@ export type InvokeComponentOptions<P> = {
* 挂载组件
*/
export function invokeComponent<P>(options: InvokeComponentOptions<P>) {
const { id, spreadsheet, params, onCleanup, component: Component } = options;
const { id, s2, params, onCleanup, component: Component } = options;

if (id) {
const domNode = document.querySelector(`#${id}`);
Expand All @@ -37,6 +37,7 @@ export function invokeComponent<P>(options: InvokeComponentOptions<P>) {
}
}

let root: Root;
const container = document.createElement('div');

if (id) {
Expand All @@ -49,8 +50,7 @@ export function invokeComponent<P>(options: InvokeComponentOptions<P>) {
let rejectCb: (reason?: unknown) => void;

function destroy() {
// const unmountResult = ReactDOM.unmountComponentAtNode(container);

root?.unmount();
if (container.parentNode) {
container.parentNode.removeChild(container);

Expand All @@ -76,8 +76,10 @@ export function invokeComponent<P>(options: InvokeComponentOptions<P>) {

function render() {
setTimeout(() => {
createRoot(container!).render(
<SpreadSheetContext.Provider value={spreadsheet}>
root = createRoot(container!);

root.render(
<SpreadSheetContext.Provider value={s2}>
<Component onCancel={close} resolver={resolveCb} params={params} />
</SpreadSheetContext.Provider>,
);
Expand Down

0 comments on commit e841d3d

Please sign in to comment.