fix(variable): fix currentObject (#2887)

* fix(variable): fix currentObject

* refactor: rename
This commit is contained in:
被雨水过滤的空气-Rain 2023-10-21 10:19:34 +08:00 committed by GitHub
parent 2dbb095529
commit dc4754750d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 82 additions and 51 deletions

View File

@ -19,7 +19,7 @@ import {
} from '../../../schema-settings/hooks/useIsAllowToSetDefaultValue';
import { LocalVariablesProvider } from '../../../variables/hooks/useLocalVariables';
import { AssociationFieldContext } from './context';
import { useAssociationFieldContext } from './hooks';
import { SubFormProvider, useAssociationFieldContext } from './hooks';
export const Nester = (props) => {
const { options } = useContext(AssociationFieldContext);
@ -78,13 +78,15 @@ const ToOneNester = (props) => {
return (
<FormActiveFieldsProvider name="nester">
<RecordProvider record={field.value}>
<LocalVariablesProvider iterationCtx={field.value}>
<DefaultValueProvider isAllowToSetDefaultValue={isAllowToSetDefaultValue}>
<Card bordered={true}>{props.children}</Card>
</DefaultValueProvider>
</LocalVariablesProvider>
</RecordProvider>
<SubFormProvider value={field.value}>
<RecordProvider record={field.value}>
<LocalVariablesProvider iterationCtx={field.value}>
<DefaultValueProvider isAllowToSetDefaultValue={isAllowToSetDefaultValue}>
<Card bordered={true}>{props.children}</Card>
</DefaultValueProvider>
</LocalVariablesProvider>
</RecordProvider>
</SubFormProvider>
</FormActiveFieldsProvider>
);
};
@ -186,19 +188,21 @@ const ToManyNester = observer(
)}
</div>
<FormActiveFieldsProvider name="nester">
<RecordProvider record={value}>
<LocalVariablesProvider iterationCtx={value}>
<RecordIndexProvider index={index}>
<DefaultValueProvider isAllowToSetDefaultValue={isAllowToSetDefaultValue}>
<RecursionField
onlyRenderProperties
basePath={field.address.concat(index)}
schema={fieldSchema}
/>
</DefaultValueProvider>
</RecordIndexProvider>
</LocalVariablesProvider>
</RecordProvider>
<SubFormProvider value={value}>
<RecordProvider record={value}>
<LocalVariablesProvider iterationCtx={value}>
<RecordIndexProvider index={index}>
<DefaultValueProvider isAllowToSetDefaultValue={isAllowToSetDefaultValue}>
<RecursionField
onlyRenderProperties
basePath={field.address.concat(index)}
schema={fieldSchema}
/>
</DefaultValueProvider>
</RecordIndexProvider>
</LocalVariablesProvider>
</RecordProvider>
</SubFormProvider>
</FormActiveFieldsProvider>
<Divider />
</React.Fragment>

View File

@ -1,10 +1,10 @@
import { GeneralField } from '@formily/core';
import { useField, useFieldSchema } from '@formily/react';
import { reaction } from '@formily/reactive';
import { flatten } from '@nocobase/utils/client';
import { flatten, getValuesByPath } from '@nocobase/utils/client';
import _, { isString } from 'lodash';
import cloneDeep from 'lodash/cloneDeep';
import { useCallback, useContext, useEffect, useMemo, useState } from 'react';
import { createContext, useCallback, useContext, useEffect, useMemo, useState } from 'react';
import { useFormBlockContext } from '../../../block-provider';
import { mergeFilter } from '../../../block-provider/SharedFilterProvider';
import { useCollection, useCollectionManager } from '../../../collection-manager';
@ -58,6 +58,7 @@ export default function useServiceOptions(props) {
const { parseFilter } = useParseDataScopeFilter();
const [fieldServiceFilter, setFieldServiceFilter] = useState(null);
const { form } = useFormBlockContext();
const { formValue: subFormValue } = useSubFormValue();
useEffect(() => {
const filterFromSchema = isString(fieldSchema?.['x-component-props']?.service?.params?.filter)
@ -72,7 +73,7 @@ export default function useServiceOptions(props) {
_run();
reaction(() => {
const dispose = reaction(() => {
// 这一步主要是为了使 reaction 能够收集到依赖
const flat = flatten(filterFromSchema, {
breakOn({ key }) {
@ -82,16 +83,28 @@ export default function useServiceOptions(props) {
if (!isVariable(value)) {
return value;
}
const result = _.get({ $nForm: form?.values }, getPath(value));
const result = getValuesByPath(
{
$nForm: form?.values,
$iteration: subFormValue,
},
getPath(value),
);
return result;
},
});
return flat;
}, run);
return dispose;
}, [
field.componentProps?.service?.params?.filter,
fieldSchema?.['x-component-props']?.service?.params?.filter,
fieldSchema,
form?.values,
parseFilter,
record,
service?.params?.filter,
subFormValue,
]);
const normalizeValues = useCallback(
@ -160,16 +173,7 @@ export default function useServiceOptions(props) {
],
'$or',
);
}, [
collectionField?.interface,
collectionField?.foreignKey,
fieldSchema,
fieldServiceFilter,
sourceValue,
params?.filter,
value,
fieldNames?.value,
]);
}, [collectionField?.interface, collectionField.foreignKey, fieldSchema, fieldServiceFilter, sourceValue]);
return useMemo(() => {
return {
@ -189,3 +193,22 @@ export const useFieldNames = (props) => {
props.fieldNames;
return { label: 'label', value: 'value', ...fieldNames };
};
const SubFormContext = createContext<Record<string, any>>(null);
export const SubFormProvider = SubFormContext.Provider;
/**
* form Proxy
*
* ##
* 1. 使 useForm form form
* 2. useRecord copy
* 3. useForm form parent
* @returns
*/
export const useSubFormValue = () => {
const context = useContext(SubFormContext);
return {
formValue: context,
};
};

View File

@ -1,6 +1,7 @@
import { Field } from '@formily/core';
import { useField, useFieldSchema } from '@formily/react';
import { reaction } from '@formily/reactive';
import { getValuesByPath } from '@nocobase/utils/client';
import _ from 'lodash';
import { useEffect } from 'react';
import { useRecord, useRecordIndex } from '../../../../../src/record-provider';
@ -102,12 +103,12 @@ const useParseDefaultValue = () => {
const path = getPath(fieldSchema.default);
// fix https://nocobase.height.app/T-2212
if (_.get(obj, path) === undefined) {
if (getValuesByPath(obj, path) === undefined) {
// 返回一个随机值,确保能触发 run 函数
return Math.random();
}
return _.get(obj, path);
return getValuesByPath(obj, path);
}, run);
return dispose;

View File

@ -24,6 +24,7 @@ import {
import { useACLFieldWhitelist } from '../../../acl/ACLProvider';
import { LocalVariablesProvider } from '../../../variables/hooks/useLocalVariables';
import { useToken } from '../__builtins__';
import { SubFormProvider } from '../association-field/hooks';
import { ColumnFieldProvider } from './components/ColumnFieldProvider';
import { extractIndex, isCollectionFieldComponent, isColumnComponent } from './utils';
@ -62,19 +63,21 @@ const useTableColumns = (props: { showDel?: boolean; isSubTable?: boolean }) =>
render: (v, record) => {
const index = field.value?.indexOf(record);
return (
<RecordIndexProvider index={record.__index || index}>
<LocalVariablesProvider iterationCtx={record}>
<RecordProvider record={record}>
<ColumnFieldProvider schema={s} basePath={field.address.concat(record.__index || index)}>
<RecursionField
basePath={field.address.concat(record.__index || index)}
schema={s}
onlyRenderProperties
/>
</ColumnFieldProvider>
</RecordProvider>
</LocalVariablesProvider>
</RecordIndexProvider>
<SubFormProvider value={record}>
<RecordIndexProvider index={record.__index || index}>
<LocalVariablesProvider iterationCtx={record}>
<RecordProvider record={record}>
<ColumnFieldProvider schema={s} basePath={field.address.concat(record.__index || index)}>
<RecursionField
basePath={field.address.concat(record.__index || index)}
schema={s}
onlyRenderProperties
/>
</ColumnFieldProvider>
</RecordProvider>
</LocalVariablesProvider>
</RecordIndexProvider>
</SubFormProvider>
);
},
} as TableColumnProps<any>;