refactor: performance optimization of association field data scope (#2113)
* refactor: performance optimization of association field data scope * refactor: disabled * refactor: disabled * refactor: code improve
This commit is contained in:
parent
ed9d716d7d
commit
a9aab8ed92
@ -13,7 +13,7 @@ export const ChildDynamicComponent = observer(
|
|||||||
const formVariabele = useFormVariable({ blockForm: form, rootCollection });
|
const formVariabele = useFormVariable({ blockForm: form, rootCollection });
|
||||||
const iterationVariabele = useIterationVariable({
|
const iterationVariabele = useIterationVariable({
|
||||||
blockForm: form,
|
blockForm: form,
|
||||||
collectionField,
|
currentCollection: collectionField.collectionName,
|
||||||
rootCollection,
|
rootCollection,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -11,11 +11,12 @@ interface GetOptionsParams {
|
|||||||
loadChildren?: (option: Option) => Promise<void>;
|
loadChildren?: (option: Option) => Promise<void>;
|
||||||
getFilterOptions?: (collectionName: string) => any[];
|
getFilterOptions?: (collectionName: string) => any[];
|
||||||
compile: (value: string) => any;
|
compile: (value: string) => any;
|
||||||
|
schema?: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
const getChildren = (
|
const getChildren = (
|
||||||
options: FieldOption[],
|
options: FieldOption[],
|
||||||
{ depth, maxDepth, loadChildren, compile }: GetOptionsParams,
|
{ depth, maxDepth, loadChildren, compile, schema }: GetOptionsParams,
|
||||||
): Option[] => {
|
): Option[] => {
|
||||||
const result = options
|
const result = options
|
||||||
.map((option): Option => {
|
.map((option): Option => {
|
||||||
@ -25,6 +26,8 @@ const getChildren = (
|
|||||||
value: option.name,
|
value: option.name,
|
||||||
label: compile(option.title),
|
label: compile(option.title),
|
||||||
depth,
|
depth,
|
||||||
|
// TODO: 现在是通过组件的名称来过滤能够被选择的选项,这样的坏处是不够精确,后续可以优化
|
||||||
|
disabled: schema?.['x-component'] !== option.schema?.['x-component'],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,11 +53,13 @@ export const useFormVariable = ({
|
|||||||
rootCollection,
|
rootCollection,
|
||||||
operator,
|
operator,
|
||||||
level,
|
level,
|
||||||
|
schema,
|
||||||
}: {
|
}: {
|
||||||
blockForm?: any;
|
blockForm?: any;
|
||||||
rootCollection: string;
|
rootCollection: string;
|
||||||
operator?: any;
|
operator?: any;
|
||||||
level?: number;
|
level?: number;
|
||||||
|
schema?: any;
|
||||||
}) => {
|
}) => {
|
||||||
const compile = useCompile();
|
const compile = useCompile();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
@ -82,6 +87,7 @@ export const useFormVariable = ({
|
|||||||
maxDepth: 4,
|
maxDepth: 4,
|
||||||
loadChildren,
|
loadChildren,
|
||||||
compile,
|
compile,
|
||||||
|
schema,
|
||||||
}) || [];
|
}) || [];
|
||||||
if (children.length === 0) {
|
if (children.length === 0) {
|
||||||
option.disabled = true;
|
option.disabled = true;
|
||||||
|
@ -1,94 +1,125 @@
|
|||||||
|
import { Schema } from '@formily/react';
|
||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
import { useCollectionManager } from '../../../collection-manager';
|
|
||||||
import { useCompile, useGetFilterOptions } from '../../../schema-component';
|
import { useCompile, useGetFilterOptions } from '../../../schema-component';
|
||||||
|
import { FieldOption, Option } from '../type';
|
||||||
|
|
||||||
interface GetOptionsParams {
|
interface GetOptionsParams {
|
||||||
schema: any;
|
depth: number;
|
||||||
operator?: string;
|
operator?: string;
|
||||||
maxDepth: number;
|
maxDepth: number;
|
||||||
count?: number;
|
count?: number;
|
||||||
getFilterOptions: (collectionName: string) => any[];
|
loadChildren?: (option: Option) => Promise<void>;
|
||||||
|
getFilterOptions?: (collectionName: string) => any[];
|
||||||
|
compile: (value: string) => any;
|
||||||
|
schema: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
const getChildren = (options: any[], { schema, operator, maxDepth, count = 1, getFilterOptions }: GetOptionsParams) => {
|
const getChildren = (
|
||||||
if (count > maxDepth) {
|
options: FieldOption[],
|
||||||
return [];
|
{ depth, maxDepth, loadChildren, compile, schema }: GetOptionsParams,
|
||||||
}
|
): Option[] => {
|
||||||
|
const result = options
|
||||||
const result = options.map((option) => {
|
.map((option): Option => {
|
||||||
if ((option.type !== 'belongsTo' && option.type !== 'hasOne') || !option.target) {
|
if (!option.target) {
|
||||||
return {
|
return {
|
||||||
key: option.name,
|
key: option.name,
|
||||||
value: option.name,
|
value: option.name,
|
||||||
label: option.title,
|
label: compile(option.title),
|
||||||
|
depth,
|
||||||
// TODO: 现在是通过组件的名称来过滤能够被选择的选项,这样的坏处是不够精确,后续可以优化
|
// TODO: 现在是通过组件的名称来过滤能够被选择的选项,这样的坏处是不够精确,后续可以优化
|
||||||
// disabled: schema?.['x-component'] !== option.schema?.['x-component'],
|
disabled: schema?.['x-component'] !== option.schema?.['x-component'],
|
||||||
disabled: false,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const children =
|
if (depth >= maxDepth) {
|
||||||
getChildren(getFilterOptions(option.target), {
|
return null;
|
||||||
schema,
|
}
|
||||||
operator,
|
|
||||||
maxDepth,
|
|
||||||
count: count + 1,
|
|
||||||
getFilterOptions,
|
|
||||||
}) || [];
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
key: option.name,
|
key: option.name,
|
||||||
value: option.name,
|
value: option.name,
|
||||||
label: option.title,
|
label: compile(option.title),
|
||||||
children,
|
children: [],
|
||||||
disabled: children.every((child) => child.disabled),
|
isLeaf: false,
|
||||||
|
field: option,
|
||||||
|
depth,
|
||||||
|
loadChildren,
|
||||||
};
|
};
|
||||||
});
|
})
|
||||||
|
.filter(Boolean);
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useIterationVariable = ({
|
export const useIterationVariable = ({
|
||||||
blockForm,
|
blockForm,
|
||||||
collectionField,
|
currentCollection,
|
||||||
operator,
|
operator,
|
||||||
schema,
|
schema,
|
||||||
level,
|
level,
|
||||||
rootCollection,
|
rootCollection,
|
||||||
}: {
|
}: {
|
||||||
blockForm?: any;
|
blockForm?: any;
|
||||||
collectionField: any;
|
currentCollection: string;
|
||||||
|
rootCollection: string;
|
||||||
operator?: any;
|
operator?: any;
|
||||||
schema?: any;
|
schema?: any;
|
||||||
level?: number;
|
level?: number;
|
||||||
rootCollection?: string;
|
|
||||||
}) => {
|
}) => {
|
||||||
const compile = useCompile();
|
const compile = useCompile();
|
||||||
const getFilterOptions = useGetFilterOptions();
|
const getFilterOptions = useGetFilterOptions();
|
||||||
const fields = getFilterOptions(collectionField?.collectionName);
|
const loadChildren = (option: any): Promise<void> => {
|
||||||
const children = useMemo(() => {
|
if (!option.field?.target) {
|
||||||
const allowFields = fields.filter((field) => {
|
return new Promise((resolve) => {
|
||||||
return Object.keys(blockForm.fields).some((name) => name.includes(field.name));
|
resolve(void 0);
|
||||||
});
|
});
|
||||||
return (
|
}
|
||||||
getChildren(allowFields, {
|
|
||||||
schema,
|
|
||||||
operator,
|
|
||||||
maxDepth: level || 3,
|
|
||||||
getFilterOptions,
|
|
||||||
}) || []
|
|
||||||
);
|
|
||||||
}, [operator, schema, blockForm]);
|
|
||||||
|
|
||||||
return useMemo(() => {
|
const collectionName = option.field.target;
|
||||||
return rootCollection !== collectionField?.collectionName && children.length > 0
|
const fields = getFilterOptions(collectionName);
|
||||||
? compile({
|
const allowFields =
|
||||||
|
option.depth === 0
|
||||||
|
? fields.filter((field) => {
|
||||||
|
return Object.keys(blockForm.fields).some((name) => name.includes(`.${field.name}`));
|
||||||
|
})
|
||||||
|
: fields;
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
setTimeout(() => {
|
||||||
|
const children =
|
||||||
|
getChildren(allowFields, {
|
||||||
|
depth: option.depth + 1,
|
||||||
|
maxDepth: 4,
|
||||||
|
loadChildren,
|
||||||
|
compile,
|
||||||
|
schema,
|
||||||
|
}) || [];
|
||||||
|
if (children.length === 0) {
|
||||||
|
option.disabled = true;
|
||||||
|
resolve();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
option.children = children;
|
||||||
|
resolve();
|
||||||
|
|
||||||
|
// 延迟 5 毫秒,防止阻塞主线程,导致 UI 卡顿
|
||||||
|
}, 5);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const result = useMemo(() => {
|
||||||
|
return (
|
||||||
|
blockForm &&
|
||||||
|
currentCollection !== rootCollection && {
|
||||||
label: `{{t("Current object")}}`,
|
label: `{{t("Current object")}}`,
|
||||||
value: '$iteration',
|
value: '$iteration',
|
||||||
key: '$iteration',
|
key: '$iteration',
|
||||||
disabled: children.every((option) => option.disabled),
|
children: [],
|
||||||
children: children,
|
isLeaf: false,
|
||||||
})
|
field: {
|
||||||
: null;
|
target: currentCollection,
|
||||||
}, [children]);
|
},
|
||||||
|
depth: 0,
|
||||||
|
loadChildren,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}, [currentCollection]);
|
||||||
|
return result;
|
||||||
};
|
};
|
||||||
|
@ -9,8 +9,13 @@ export const useVariableOptions = ({ form, collectionField, rootCollection }: an
|
|||||||
const { operator, schema } = useValues();
|
const { operator, schema } = useValues();
|
||||||
const userVariable = useUserVariable({ maxDepth: 3, schema });
|
const userVariable = useUserVariable({ maxDepth: 3, schema });
|
||||||
const dateVariable = useDateVariable({ operator, schema });
|
const dateVariable = useDateVariable({ operator, schema });
|
||||||
const formVariabele = useFormVariable({ blockForm: form, rootCollection });
|
const formVariabele = useFormVariable({ blockForm: form, schema, rootCollection });
|
||||||
const iterationVariabele = useIterationVariable({ blockForm: form, collectionField, schema, rootCollection });
|
const iterationVariabele = useIterationVariable({
|
||||||
|
blockForm: form,
|
||||||
|
currentCollection: collectionField.collectionName,
|
||||||
|
schema,
|
||||||
|
rootCollection,
|
||||||
|
});
|
||||||
|
|
||||||
const result = useMemo(
|
const result = useMemo(
|
||||||
() => [userVariable, dateVariable, formVariabele, iterationVariabele].filter(Boolean),
|
() => [userVariable, dateVariable, formVariabele, iterationVariabele].filter(Boolean),
|
||||||
|
Loading…
Reference in New Issue
Block a user