fix(subtable): should not have a value by default and fix key of table (#2763)
* fix(subtable): should not have a value by default and fix key of table * fix(subtable): fix invalid to set default value
This commit is contained in:
parent
8f29fde008
commit
3b76a84605
@ -91,7 +91,7 @@ export const SubTable: any = observer(
|
|||||||
onClick={() => {
|
onClick={() => {
|
||||||
field.value = field.value || [];
|
field.value = field.value || [];
|
||||||
field.value.push({});
|
field.value.push({});
|
||||||
void field.onInput(field.value);
|
field.onInput(field.value);
|
||||||
}}
|
}}
|
||||||
icon={<PlusOutlined />}
|
icon={<PlusOutlined />}
|
||||||
>
|
>
|
||||||
|
@ -72,9 +72,8 @@ const useParseDefaultValue = () => {
|
|||||||
setDefaultValue(value);
|
setDefaultValue(value);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// TODO: 可能会因为异步时序问题导致设置默认值无效
|
|
||||||
// eslint-disable-next-line promise/catch-or-return
|
// eslint-disable-next-line promise/catch-or-return
|
||||||
void Promise.resolve().then(() => {
|
Promise.resolve().then(() => {
|
||||||
field.setInitialValue(value);
|
field.setInitialValue(value);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -91,7 +90,7 @@ const useParseDefaultValue = () => {
|
|||||||
// 使用防抖,提高性能和用户体验
|
// 使用防抖,提高性能和用户体验
|
||||||
const run = _.debounce(_run, DEBOUNCE_WAIT);
|
const run = _.debounce(_run, DEBOUNCE_WAIT);
|
||||||
|
|
||||||
void _run();
|
_run();
|
||||||
|
|
||||||
if (isVariable(fieldSchema.default)) {
|
if (isVariable(fieldSchema.default)) {
|
||||||
const variableName = getVariableName(fieldSchema.default);
|
const variableName = getVariableName(fieldSchema.default);
|
||||||
|
@ -162,13 +162,14 @@ export function isFromDatabase(value: Record<string, any>) {
|
|||||||
export const useSubTableSpecialCase = ({ field }) => {
|
export const useSubTableSpecialCase = ({ field }) => {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (_.isEmpty(field.value)) {
|
if (_.isEmpty(field.value)) {
|
||||||
|
const value = field.value;
|
||||||
field.value = [{}];
|
field.value = [{}];
|
||||||
// 因为默认值的解析是异步的,所以下面的代码会优先于默认值的设置,这样就防止了设置完默认值后又被清空的问题
|
// 因为默认值的解析是异步的,所以下面的代码会优先于默认值的设置,这样就防止了设置完默认值后又被清空的问题
|
||||||
Promise.resolve()
|
setTimeout(() => {
|
||||||
.then(() => {
|
if (JSON.stringify(field.value) === '[{}]') {
|
||||||
field.value = [];
|
field.value = value;
|
||||||
})
|
}
|
||||||
.catch(console.error);
|
});
|
||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
};
|
};
|
||||||
|
@ -6,11 +6,12 @@ import { ArrayField } from '@formily/core';
|
|||||||
import { spliceArrayState } from '@formily/core/esm/shared/internals';
|
import { spliceArrayState } from '@formily/core/esm/shared/internals';
|
||||||
import { RecursionField, Schema, observer, useField, useFieldSchema } from '@formily/react';
|
import { RecursionField, Schema, observer, useField, useFieldSchema } from '@formily/react';
|
||||||
import { action } from '@formily/reactive';
|
import { action } from '@formily/reactive';
|
||||||
|
import { uid } from '@formily/shared';
|
||||||
import { isPortalInBody } from '@nocobase/utils/client';
|
import { isPortalInBody } from '@nocobase/utils/client';
|
||||||
import { useMemoizedFn } from 'ahooks';
|
import { useMemoizedFn } from 'ahooks';
|
||||||
import { Table as AntdTable, TableColumnProps } from 'antd';
|
import { Table as AntdTable, TableColumnProps } from 'antd';
|
||||||
import { default as classNames, default as cls } from 'classnames';
|
import { default as classNames, default as cls } from 'classnames';
|
||||||
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { DndContext, useDesignable, useTableSize } from '../..';
|
import { DndContext, useDesignable, useTableSize } from '../..';
|
||||||
import {
|
import {
|
||||||
@ -101,12 +102,13 @@ const useTableColumns = (props: { showDel?: boolean; isSubTable?: boolean }) =>
|
|||||||
<DeleteOutlined
|
<DeleteOutlined
|
||||||
style={{ cursor: 'pointer' }}
|
style={{ cursor: 'pointer' }}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
void action(() => {
|
action(() => {
|
||||||
spliceArrayState(field as any, {
|
spliceArrayState(field as any, {
|
||||||
startIndex: index,
|
startIndex: index,
|
||||||
deleteCount: 1,
|
deleteCount: 1,
|
||||||
});
|
});
|
||||||
field.value.splice(index, 1);
|
field.value.splice(index, 1);
|
||||||
|
field.initialValue?.splice(index, 1);
|
||||||
return field.onInput(field.value);
|
return field.onInput(field.value);
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
@ -231,6 +233,7 @@ export const Table: any = observer(
|
|||||||
const [selectedRow, setSelectedRow] = useState([]);
|
const [selectedRow, setSelectedRow] = useState([]);
|
||||||
const dataSource = field?.value?.slice?.()?.filter?.(Boolean) || [];
|
const dataSource = field?.value?.slice?.()?.filter?.(Boolean) || [];
|
||||||
const isRowSelect = rowSelection?.type !== 'none';
|
const isRowSelect = rowSelection?.type !== 'none';
|
||||||
|
const defaultRowKeyMap = useRef(new Map());
|
||||||
let onRow = null,
|
let onRow = null,
|
||||||
highlightRow = '';
|
highlightRow = '';
|
||||||
|
|
||||||
@ -339,8 +342,29 @@ export const Table: any = observer(
|
|||||||
};
|
};
|
||||||
}, [field, onRowDragEnd, dragSort]);
|
}, [field, onRowDragEnd, dragSort]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 为没有设置 key 属性的 record 生成一个唯一的 key
|
||||||
|
* 1. rowKey 的默认值是 “key”,所以先判断有没有 record.key;
|
||||||
|
* 2. 如果没有就生成一个唯一的 key,并以 record 的值作为索引;
|
||||||
|
* 3. 这样下次就能取到对应的 key 的值;
|
||||||
|
*
|
||||||
|
* 这里有效的前提是:数组中对应的 record 的引用不会发生改变。
|
||||||
|
*
|
||||||
|
* @param record
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
const defaultRowKey = (record: any) => {
|
const defaultRowKey = (record: any) => {
|
||||||
return field.value?.indexOf?.(record);
|
if (record.key) {
|
||||||
|
return record.key;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (defaultRowKeyMap.current.has(record)) {
|
||||||
|
return defaultRowKeyMap.current.get(record);
|
||||||
|
}
|
||||||
|
|
||||||
|
const key = uid();
|
||||||
|
defaultRowKeyMap.current.set(record, key);
|
||||||
|
return key;
|
||||||
};
|
};
|
||||||
|
|
||||||
const getRowKey = (record: any) => {
|
const getRowKey = (record: any) => {
|
||||||
|
@ -1 +1 @@
|
|||||||
export const DEBOUNCE_WAIT = 500;
|
export const DEBOUNCE_WAIT = 300;
|
||||||
|
Loading…
Reference in New Issue
Block a user