fix(variable): fix currentObject (#2887)
* fix(variable): fix currentObject * refactor: rename
This commit is contained in:
parent
2dbb095529
commit
dc4754750d
@ -19,7 +19,7 @@ import {
|
|||||||
} from '../../../schema-settings/hooks/useIsAllowToSetDefaultValue';
|
} from '../../../schema-settings/hooks/useIsAllowToSetDefaultValue';
|
||||||
import { LocalVariablesProvider } from '../../../variables/hooks/useLocalVariables';
|
import { LocalVariablesProvider } from '../../../variables/hooks/useLocalVariables';
|
||||||
import { AssociationFieldContext } from './context';
|
import { AssociationFieldContext } from './context';
|
||||||
import { useAssociationFieldContext } from './hooks';
|
import { SubFormProvider, useAssociationFieldContext } from './hooks';
|
||||||
|
|
||||||
export const Nester = (props) => {
|
export const Nester = (props) => {
|
||||||
const { options } = useContext(AssociationFieldContext);
|
const { options } = useContext(AssociationFieldContext);
|
||||||
@ -78,13 +78,15 @@ const ToOneNester = (props) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<FormActiveFieldsProvider name="nester">
|
<FormActiveFieldsProvider name="nester">
|
||||||
<RecordProvider record={field.value}>
|
<SubFormProvider value={field.value}>
|
||||||
<LocalVariablesProvider iterationCtx={field.value}>
|
<RecordProvider record={field.value}>
|
||||||
<DefaultValueProvider isAllowToSetDefaultValue={isAllowToSetDefaultValue}>
|
<LocalVariablesProvider iterationCtx={field.value}>
|
||||||
<Card bordered={true}>{props.children}</Card>
|
<DefaultValueProvider isAllowToSetDefaultValue={isAllowToSetDefaultValue}>
|
||||||
</DefaultValueProvider>
|
<Card bordered={true}>{props.children}</Card>
|
||||||
</LocalVariablesProvider>
|
</DefaultValueProvider>
|
||||||
</RecordProvider>
|
</LocalVariablesProvider>
|
||||||
|
</RecordProvider>
|
||||||
|
</SubFormProvider>
|
||||||
</FormActiveFieldsProvider>
|
</FormActiveFieldsProvider>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@ -186,19 +188,21 @@ const ToManyNester = observer(
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<FormActiveFieldsProvider name="nester">
|
<FormActiveFieldsProvider name="nester">
|
||||||
<RecordProvider record={value}>
|
<SubFormProvider value={value}>
|
||||||
<LocalVariablesProvider iterationCtx={value}>
|
<RecordProvider record={value}>
|
||||||
<RecordIndexProvider index={index}>
|
<LocalVariablesProvider iterationCtx={value}>
|
||||||
<DefaultValueProvider isAllowToSetDefaultValue={isAllowToSetDefaultValue}>
|
<RecordIndexProvider index={index}>
|
||||||
<RecursionField
|
<DefaultValueProvider isAllowToSetDefaultValue={isAllowToSetDefaultValue}>
|
||||||
onlyRenderProperties
|
<RecursionField
|
||||||
basePath={field.address.concat(index)}
|
onlyRenderProperties
|
||||||
schema={fieldSchema}
|
basePath={field.address.concat(index)}
|
||||||
/>
|
schema={fieldSchema}
|
||||||
</DefaultValueProvider>
|
/>
|
||||||
</RecordIndexProvider>
|
</DefaultValueProvider>
|
||||||
</LocalVariablesProvider>
|
</RecordIndexProvider>
|
||||||
</RecordProvider>
|
</LocalVariablesProvider>
|
||||||
|
</RecordProvider>
|
||||||
|
</SubFormProvider>
|
||||||
</FormActiveFieldsProvider>
|
</FormActiveFieldsProvider>
|
||||||
<Divider />
|
<Divider />
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import { GeneralField } from '@formily/core';
|
import { GeneralField } from '@formily/core';
|
||||||
import { useField, useFieldSchema } from '@formily/react';
|
import { useField, useFieldSchema } from '@formily/react';
|
||||||
import { reaction } from '@formily/reactive';
|
import { reaction } from '@formily/reactive';
|
||||||
import { flatten } from '@nocobase/utils/client';
|
import { flatten, getValuesByPath } from '@nocobase/utils/client';
|
||||||
import _, { isString } from 'lodash';
|
import _, { isString } from 'lodash';
|
||||||
import cloneDeep from 'lodash/cloneDeep';
|
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 { useFormBlockContext } from '../../../block-provider';
|
||||||
import { mergeFilter } from '../../../block-provider/SharedFilterProvider';
|
import { mergeFilter } from '../../../block-provider/SharedFilterProvider';
|
||||||
import { useCollection, useCollectionManager } from '../../../collection-manager';
|
import { useCollection, useCollectionManager } from '../../../collection-manager';
|
||||||
@ -58,6 +58,7 @@ export default function useServiceOptions(props) {
|
|||||||
const { parseFilter } = useParseDataScopeFilter();
|
const { parseFilter } = useParseDataScopeFilter();
|
||||||
const [fieldServiceFilter, setFieldServiceFilter] = useState(null);
|
const [fieldServiceFilter, setFieldServiceFilter] = useState(null);
|
||||||
const { form } = useFormBlockContext();
|
const { form } = useFormBlockContext();
|
||||||
|
const { formValue: subFormValue } = useSubFormValue();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const filterFromSchema = isString(fieldSchema?.['x-component-props']?.service?.params?.filter)
|
const filterFromSchema = isString(fieldSchema?.['x-component-props']?.service?.params?.filter)
|
||||||
@ -72,7 +73,7 @@ export default function useServiceOptions(props) {
|
|||||||
|
|
||||||
_run();
|
_run();
|
||||||
|
|
||||||
reaction(() => {
|
const dispose = reaction(() => {
|
||||||
// 这一步主要是为了使 reaction 能够收集到依赖
|
// 这一步主要是为了使 reaction 能够收集到依赖
|
||||||
const flat = flatten(filterFromSchema, {
|
const flat = flatten(filterFromSchema, {
|
||||||
breakOn({ key }) {
|
breakOn({ key }) {
|
||||||
@ -82,16 +83,28 @@ export default function useServiceOptions(props) {
|
|||||||
if (!isVariable(value)) {
|
if (!isVariable(value)) {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
const result = _.get({ $nForm: form?.values }, getPath(value));
|
const result = getValuesByPath(
|
||||||
|
{
|
||||||
|
$nForm: form?.values,
|
||||||
|
$iteration: subFormValue,
|
||||||
|
},
|
||||||
|
getPath(value),
|
||||||
|
);
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
return flat;
|
return flat;
|
||||||
}, run);
|
}, run);
|
||||||
|
|
||||||
|
return dispose;
|
||||||
}, [
|
}, [
|
||||||
field.componentProps?.service?.params?.filter,
|
field.componentProps?.service?.params?.filter,
|
||||||
fieldSchema?.['x-component-props']?.service?.params?.filter,
|
fieldSchema,
|
||||||
|
form?.values,
|
||||||
|
parseFilter,
|
||||||
|
record,
|
||||||
service?.params?.filter,
|
service?.params?.filter,
|
||||||
|
subFormValue,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const normalizeValues = useCallback(
|
const normalizeValues = useCallback(
|
||||||
@ -160,16 +173,7 @@ export default function useServiceOptions(props) {
|
|||||||
],
|
],
|
||||||
'$or',
|
'$or',
|
||||||
);
|
);
|
||||||
}, [
|
}, [collectionField?.interface, collectionField.foreignKey, fieldSchema, fieldServiceFilter, sourceValue]);
|
||||||
collectionField?.interface,
|
|
||||||
collectionField?.foreignKey,
|
|
||||||
fieldSchema,
|
|
||||||
fieldServiceFilter,
|
|
||||||
sourceValue,
|
|
||||||
params?.filter,
|
|
||||||
value,
|
|
||||||
fieldNames?.value,
|
|
||||||
]);
|
|
||||||
|
|
||||||
return useMemo(() => {
|
return useMemo(() => {
|
||||||
return {
|
return {
|
||||||
@ -189,3 +193,22 @@ export const useFieldNames = (props) => {
|
|||||||
props.fieldNames;
|
props.fieldNames;
|
||||||
return { label: 'label', value: 'value', ...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,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { Field } from '@formily/core';
|
import { Field } from '@formily/core';
|
||||||
import { useField, useFieldSchema } from '@formily/react';
|
import { useField, useFieldSchema } from '@formily/react';
|
||||||
import { reaction } from '@formily/reactive';
|
import { reaction } from '@formily/reactive';
|
||||||
|
import { getValuesByPath } from '@nocobase/utils/client';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
import { useRecord, useRecordIndex } from '../../../../../src/record-provider';
|
import { useRecord, useRecordIndex } from '../../../../../src/record-provider';
|
||||||
@ -102,12 +103,12 @@ const useParseDefaultValue = () => {
|
|||||||
const path = getPath(fieldSchema.default);
|
const path = getPath(fieldSchema.default);
|
||||||
|
|
||||||
// fix https://nocobase.height.app/T-2212
|
// fix https://nocobase.height.app/T-2212
|
||||||
if (_.get(obj, path) === undefined) {
|
if (getValuesByPath(obj, path) === undefined) {
|
||||||
// 返回一个随机值,确保能触发 run 函数
|
// 返回一个随机值,确保能触发 run 函数
|
||||||
return Math.random();
|
return Math.random();
|
||||||
}
|
}
|
||||||
|
|
||||||
return _.get(obj, path);
|
return getValuesByPath(obj, path);
|
||||||
}, run);
|
}, run);
|
||||||
|
|
||||||
return dispose;
|
return dispose;
|
||||||
|
@ -24,6 +24,7 @@ import {
|
|||||||
import { useACLFieldWhitelist } from '../../../acl/ACLProvider';
|
import { useACLFieldWhitelist } from '../../../acl/ACLProvider';
|
||||||
import { LocalVariablesProvider } from '../../../variables/hooks/useLocalVariables';
|
import { LocalVariablesProvider } from '../../../variables/hooks/useLocalVariables';
|
||||||
import { useToken } from '../__builtins__';
|
import { useToken } from '../__builtins__';
|
||||||
|
import { SubFormProvider } from '../association-field/hooks';
|
||||||
import { ColumnFieldProvider } from './components/ColumnFieldProvider';
|
import { ColumnFieldProvider } from './components/ColumnFieldProvider';
|
||||||
import { extractIndex, isCollectionFieldComponent, isColumnComponent } from './utils';
|
import { extractIndex, isCollectionFieldComponent, isColumnComponent } from './utils';
|
||||||
|
|
||||||
@ -62,19 +63,21 @@ const useTableColumns = (props: { showDel?: boolean; isSubTable?: boolean }) =>
|
|||||||
render: (v, record) => {
|
render: (v, record) => {
|
||||||
const index = field.value?.indexOf(record);
|
const index = field.value?.indexOf(record);
|
||||||
return (
|
return (
|
||||||
<RecordIndexProvider index={record.__index || index}>
|
<SubFormProvider value={record}>
|
||||||
<LocalVariablesProvider iterationCtx={record}>
|
<RecordIndexProvider index={record.__index || index}>
|
||||||
<RecordProvider record={record}>
|
<LocalVariablesProvider iterationCtx={record}>
|
||||||
<ColumnFieldProvider schema={s} basePath={field.address.concat(record.__index || index)}>
|
<RecordProvider record={record}>
|
||||||
<RecursionField
|
<ColumnFieldProvider schema={s} basePath={field.address.concat(record.__index || index)}>
|
||||||
basePath={field.address.concat(record.__index || index)}
|
<RecursionField
|
||||||
schema={s}
|
basePath={field.address.concat(record.__index || index)}
|
||||||
onlyRenderProperties
|
schema={s}
|
||||||
/>
|
onlyRenderProperties
|
||||||
</ColumnFieldProvider>
|
/>
|
||||||
</RecordProvider>
|
</ColumnFieldProvider>
|
||||||
</LocalVariablesProvider>
|
</RecordProvider>
|
||||||
</RecordIndexProvider>
|
</LocalVariablesProvider>
|
||||||
|
</RecordIndexProvider>
|
||||||
|
</SubFormProvider>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
} as TableColumnProps<any>;
|
} as TableColumnProps<any>;
|
||||||
|
Loading…
Reference in New Issue
Block a user