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:
被雨水过滤的空气-Rain 2023-10-08 20:55:30 +08:00 committed by GitHub
parent 8f29fde008
commit 3b76a84605
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 37 additions and 13 deletions

View File

@ -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 />}
> >

View File

@ -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);

View File

@ -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); });
} }
}, []); }, []);
}; };

View File

@ -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) => {

View File

@ -1 +1 @@
export const DEBOUNCE_WAIT = 500; export const DEBOUNCE_WAIT = 300;