Skip to content

Commit

Permalink
fix: 修复 formList 嵌套赋值问题 (#1819)
Browse files Browse the repository at this point in the history
* fix: 修复 formList 嵌套赋值问题

* fix: 修复 validate 比对 name 字段序列化问题
  • Loading branch information
honkinglin authored Dec 19, 2022
1 parent 59efe3d commit f9708eb
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 31 deletions.
1 change: 1 addition & 0 deletions src/form/FormItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ export interface FormItemInstance {
setValidateMessage?: Function;
resetValidate?: Function;
validateOnly?: Function;
isFormList?: boolean;
}

const FormItem = forwardRef<FormItemInstance, FormItemProps>((props, ref) => {
Expand Down
77 changes: 50 additions & 27 deletions src/form/FormList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ const FormList = (props: TdFormListProps) => {
};

// 外部设置 fields 优先级最高,可以更改渲染的节点
function setListFields(fieldData: any[], callback: Function) {
function setListFields(fieldData: any[], callback: Function, originData) {
setFields(
fieldData.map((_, index) => ({
key: (key += 1),
Expand All @@ -80,9 +80,20 @@ const FormList = (props: TdFormListProps) => {
})),
);
// 添加至队列中 等待下次渲染完成执行对应逻辑
fieldsTaskQueueRef.current.push({ callback, fieldData });
fieldsTaskQueueRef.current.push({ callback, fieldData, originData });
}

useEffect(() => {
if (!name || !formMapRef) return;
formMapRef.current.set(name, formListRef);

return () => {
// eslint-disable-next-line react-hooks/exhaustive-deps
formMapRef.current.delete(name);
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [name]);

useEffect(() => {
[...formListMapRef.current.values()].forEach((formItemRef) => {
if (!formItemRef.current) return;
Expand All @@ -102,31 +113,35 @@ const FormList = (props: TdFormListProps) => {
const currentQueue = fieldsTaskQueueRef.current.pop();
if (!currentQueue) return;

[...formListMapRef.current.values()].forEach((formItemRef) => {
if (!formItemRef.current) return;
const { fieldData, callback, originData } = currentQueue;
// 等待子节点渲染完毕
Promise.resolve().then(() => {
[...formListMapRef.current.values()].forEach((formItemRef) => {
if (!formItemRef.current) return;

const { name } = formItemRef.current;
const { fieldData, callback } = currentQueue;
const data = get(fieldData, name);
callback(formItemRef, data);
});
}, [form, name, fields]);
const { name: itemName } = formItemRef.current;
const data = get(fieldData, itemName);
callback(formItemRef, data);
});

useEffect(() => {
if (!name || !formMapRef) return;
formMapRef.current.set(name, formListRef);
// formList 嵌套 formList
if (!formMapRef || !formMapRef.current) return;
[...formMapRef.current.values()].forEach((formItemRef) => {
if (!formItemRef.current) return;

return () => {
// eslint-disable-next-line react-hooks/exhaustive-deps
formMapRef.current.delete(name);
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [name]);
const { name: itemName, isFormList } = formItemRef.current;
if (String(itemName) === String(name) || !isFormList) return;
const data = get(originData, itemName);
if (data) callback(formItemRef, data);
});
});
}, [form, name, fields, formMapRef]);

useImperativeHandle(
formListRef,
(): FormItemInstance => ({
name,
isFormList: true,
getValue() {
const formListValue = [];
[...formListMapRef.current.values()].forEach((formItemRef) => {
Expand Down Expand Up @@ -159,16 +174,24 @@ const FormList = (props: TdFormListProps) => {
});
},
// TODO 支持局部更新数据
setValue: (fieldData: any[]) => {
setListFields(fieldData, (formItemRef, data) => {
formItemRef?.current?.setValue?.(data);
});
setValue: (fieldData: any[], originData) => {
setListFields(
fieldData,
(formItemRef, data) => {
formItemRef?.current?.setValue?.(data);
},
originData,
);
},
setField: (fieldData: { value?: any[]; status?: string }) => {
setField: (fieldData: { value?: any[]; status?: string }, originData) => {
const { value, status } = fieldData;
setListFields(value, (formItemRef, data) => {
formItemRef?.current?.setField?.({ value: data, status });
});
setListFields(
value,
(formItemRef, data) => {
formItemRef?.current?.setField?.({ value: data, status });
},
originData,
);
},
resetField: () => {
[...formListMapRef.current.values()].forEach((formItemRef) => {
Expand Down
8 changes: 4 additions & 4 deletions src/form/hooks/useInstance.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ import { getMapValue, travelMapFromObject, calcFieldValue } from '../utils';
import log from '../../_common/js/log';

// 检测是否需要校验 默认全量校验
function needValidate(name: string, fields: string[]) {
function needValidate(name: NamePath, fields: string[]) {
if (!fields || !Array.isArray(fields)) return true;
return fields.indexOf(name) !== -1;
return fields.some((item) => String(item) === String(name));
}

// 整理校验结果
Expand Down Expand Up @@ -138,7 +138,7 @@ export default function useInstance(props: TdFormProps, formRef, formMapRef: Rea
// 对外方法,设置对应 formItem 的值
function setFieldsValue(fields = {}) {
travelMapFromObject(fields, formMapRef, (formItemRef, fieldValue) => {
formItemRef?.current?.setValue?.(fieldValue);
formItemRef?.current?.setValue?.(fieldValue, fields);
});
}

Expand All @@ -150,7 +150,7 @@ export default function useInstance(props: TdFormProps, formRef, formMapRef: Rea
const { name, ...restFields } = field;
const formItemRef = getMapValue(name, formMapRef);

formItemRef?.current?.setField({ ...restFields });
formItemRef?.current?.setField(restFields, field);
});
}

Expand Down

0 comments on commit f9708eb

Please sign in to comment.