diff --git a/packages/core/client/src/block-provider/hooks/index.ts b/packages/core/client/src/block-provider/hooks/index.ts index 20066487b5..97f4d57337 100644 --- a/packages/core/client/src/block-provider/hooks/index.ts +++ b/packages/core/client/src/block-provider/hooks/index.ts @@ -28,6 +28,7 @@ import { useCollectionRecord, useDataSourceHeaders, useFormActiveFields, + useParsedFilter, useRouterBasename, useTableBlockContext, } from '../..'; @@ -1247,6 +1248,7 @@ export const useAssociationFilterBlockProps = () => { const { props: blockProps } = useBlockRequestContext(); const headers = useDataSourceHeaders(blockProps?.dataSource); const cm = useCollectionManager_deprecated(); + const { filter, parseVariableLoading } = useParsedFilter({ filterOption: field.componentProps?.params?.filter }); let list, handleSearchInput, params, run, data, valueKey, labelKey, filterKey; @@ -1266,6 +1268,7 @@ export const useAssociationFilterBlockProps = () => { pageSize: 200, page: 1, ...field.componentProps?.params, + filter, }, }, { @@ -1277,12 +1280,20 @@ export const useAssociationFilterBlockProps = () => { useEffect(() => { // 由于选项字段不需要触发当前请求,所以请求单独在关系字段的时候触发 - if (!isOptionalField(collectionField)) { + if (!isOptionalField(collectionField) && parseVariableLoading === false) { run(); } // do not format the dependencies - }, [collectionField, labelKey, run, valueKey, field.componentProps?.params, field.componentProps?.params?.sort]); + }, [ + collectionField, + labelKey, + run, + valueKey, + field.componentProps?.params, + field.componentProps?.params?.sort, + parseVariableLoading, + ]); if (!collectionField) { return {}; diff --git a/packages/core/client/src/schema-component/antd/association-field/hooks.ts b/packages/core/client/src/schema-component/antd/association-field/hooks.ts index 8e4e812be3..591214683c 100644 --- a/packages/core/client/src/schema-component/antd/association-field/hooks.ts +++ b/packages/core/client/src/schema-component/antd/association-field/hooks.ts @@ -9,21 +9,15 @@ import { GeneralField } from '@formily/core'; import { useField, useFieldSchema } from '@formily/react'; -import { reaction } from '@formily/reactive'; -import { flatten, getValuesByPath } from '@nocobase/utils/client'; -import _, { isString } from 'lodash'; +import { isString } from 'lodash'; import cloneDeep from 'lodash/cloneDeep'; -import { createContext, useCallback, useContext, useEffect, useMemo, useState } from 'react'; +import { createContext, useCallback, useContext, useMemo } from 'react'; +import { useParsedFilter } from '../../../block-provider/hooks/useParsedFilter'; import { useCollectionManager_deprecated, useCollection_deprecated } from '../../../collection-manager'; import { Collection } from '../../../data-source'; import { isInFilterFormBlock } from '../../../filter-provider'; import { mergeFilter } from '../../../filter-provider/utils'; import { useRecord } from '../../../record-provider'; -import { useParseDataScopeFilter } from '../../../schema-settings'; -import { DEBOUNCE_WAIT } from '../../../variables'; -import { getPath } from '../../../variables/utils/getPath'; -import { getVariableName } from '../../../variables/utils/getVariableName'; -import { isVariable } from '../../../variables/utils/isVariable'; import { useDesignable } from '../../hooks'; import { AssociationFieldMode } from './AssociationFieldModeProvider'; import { AssociationFieldContext } from './context'; @@ -65,66 +59,12 @@ export default function useServiceOptions(props) { const { getField } = useCollection_deprecated(); const { getCollectionJoinField } = useCollectionManager_deprecated(); const record = useRecord(); - const { parseFilter, findVariable } = useParseDataScopeFilter(); - const [fieldServiceFilter, setFieldServiceFilter] = useState(null); - - useEffect(() => { - const filterFromSchema = isString(fieldSchema?.['x-component-props']?.service?.params?.filter) + const filterParams = + (isString(fieldSchema?.['x-component-props']?.service?.params?.filter) ? field.componentProps?.service?.params?.filter - : fieldSchema?.['x-component-props']?.service?.params?.filter; + : fieldSchema?.['x-component-props']?.service?.params?.filter) || service?.params?.filter; - const _run = async () => { - const result = await parseFilter(mergeFilter([filterFromSchema || service?.params?.filter])); - setFieldServiceFilter(result); - }; - const run = _.debounce(_run, DEBOUNCE_WAIT); - - _run(); - - const dispose = reaction( - () => { - // 这一步主要是为了使 reaction 能够收集到依赖 - const flat = flatten(filterFromSchema, { - breakOn({ key }) { - return key.startsWith('$') && key !== '$and' && key !== '$or'; - }, - transformValue(value) { - if (!isVariable(value)) { - return value; - } - const variableName = getVariableName(value); - const variable = findVariable(variableName); - - if (process.env.NODE_ENV !== 'production' && !variable) { - throw new Error(`useServiceOptions: can not find variable ${variableName}`); - } - - const result = getValuesByPath( - { - [variableName]: variable?.ctx || {}, - }, - getPath(value), - ); - return result; - }, - }); - return flat; - }, - run, - { - equals: _.isEqual, - }, - ); - - return dispose; - }, [ - field.componentProps?.service?.params?.filter, - fieldSchema, - findVariable, - parseFilter, - record, - service?.params?.filter, - ]); + const { filter: parsedFilterParams } = useParsedFilter({ filterOption: filterParams }); const collectionField = useMemo(() => { return getField(fieldSchema.name) || getCollectionJoinField(fieldSchema?.['x-collection-field']); @@ -143,7 +83,7 @@ export default function useServiceOptions(props) { }, } : null, - fieldServiceFilter, + parsedFilterParams, ]), isOToAny && sourceValue !== undefined && @@ -171,7 +111,7 @@ export default function useServiceOptions(props) { collectionField?.interface, collectionField?.foreignKey, fieldSchema, - fieldServiceFilter, + parsedFilterParams, sourceValue, useOriginalFilter, ]);