fix: record picker cannot select data when editing (#2798)
* fix: record picker cannot select data when editing * refactor: rename file name * fix: just run the lazy load once * test: add test * test: fix test * chore: better comment --------- Co-authored-by: Rain <958414905@qq.com>
This commit is contained in:
parent
2dc964d4f1
commit
72367a9f85
367
packages/core/client/src/__tests__/e2e/bugs/T-2200.test.ts
Normal file
367
packages/core/client/src/__tests__/e2e/bugs/T-2200.test.ts
Normal file
@ -0,0 +1,367 @@
|
|||||||
|
import { expect, test } from '@nocobase/test/client';
|
||||||
|
|
||||||
|
const config = {
|
||||||
|
pageSchema: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Page',
|
||||||
|
properties: {
|
||||||
|
n7k4be0tpgt: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Grid',
|
||||||
|
'x-initializer': 'BlockInitializers',
|
||||||
|
properties: {
|
||||||
|
ai6ojrzwkiv: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Grid.Row',
|
||||||
|
properties: {
|
||||||
|
amsy67ggjr3: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Grid.Col',
|
||||||
|
properties: {
|
||||||
|
ajob701dt18: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-decorator': 'TableBlockProvider',
|
||||||
|
'x-acl-action': 'users:list',
|
||||||
|
'x-decorator-props': {
|
||||||
|
collection: 'users',
|
||||||
|
resource: 'users',
|
||||||
|
action: 'list',
|
||||||
|
params: {
|
||||||
|
pageSize: 20,
|
||||||
|
},
|
||||||
|
rowKey: 'id',
|
||||||
|
showIndex: true,
|
||||||
|
dragSort: false,
|
||||||
|
disableTemplate: false,
|
||||||
|
},
|
||||||
|
'x-designer': 'TableBlockDesigner',
|
||||||
|
'x-component': 'CardItem',
|
||||||
|
'x-filter-targets': [],
|
||||||
|
properties: {
|
||||||
|
actions: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-initializer': 'TableActionInitializers',
|
||||||
|
'x-component': 'ActionBar',
|
||||||
|
'x-component-props': {
|
||||||
|
style: {
|
||||||
|
marginBottom: 'var(--nb-spacing)',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': 'farfrcvsydq',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 1,
|
||||||
|
},
|
||||||
|
t1o3f4r1j4q: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'array',
|
||||||
|
'x-initializer': 'TableColumnInitializers',
|
||||||
|
'x-component': 'TableV2',
|
||||||
|
'x-component-props': {
|
||||||
|
rowKey: 'id',
|
||||||
|
rowSelection: {
|
||||||
|
type: 'checkbox',
|
||||||
|
},
|
||||||
|
useProps: '{{ useTableBlockProps }}',
|
||||||
|
},
|
||||||
|
properties: {
|
||||||
|
actions: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
title: '{{ t("Actions") }}',
|
||||||
|
'x-action-column': 'actions',
|
||||||
|
'x-decorator': 'TableV2.Column.ActionBar',
|
||||||
|
'x-component': 'TableV2.Column',
|
||||||
|
'x-designer': 'TableV2.ActionColumnDesigner',
|
||||||
|
'x-initializer': 'TableActionColumnInitializers',
|
||||||
|
properties: {
|
||||||
|
actions: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-decorator': 'DndContext',
|
||||||
|
'x-component': 'Space',
|
||||||
|
'x-component-props': {
|
||||||
|
split: '|',
|
||||||
|
},
|
||||||
|
properties: {
|
||||||
|
ezur2k7gz8k: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
title: '{{ t("Edit") }}',
|
||||||
|
'x-action': 'update',
|
||||||
|
'x-designer': 'Action.Designer',
|
||||||
|
'x-component': 'Action.Link',
|
||||||
|
'x-component-props': {
|
||||||
|
openMode: 'drawer',
|
||||||
|
icon: 'EditOutlined',
|
||||||
|
},
|
||||||
|
'x-decorator': 'ACLActionProvider',
|
||||||
|
'x-designer-props': {
|
||||||
|
linkageAction: true,
|
||||||
|
},
|
||||||
|
properties: {
|
||||||
|
drawer: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
title: '{{ t("Edit record") }}',
|
||||||
|
'x-component': 'Action.Container',
|
||||||
|
'x-component-props': {
|
||||||
|
className: 'nb-action-popup',
|
||||||
|
},
|
||||||
|
properties: {
|
||||||
|
tabs: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Tabs',
|
||||||
|
'x-component-props': {},
|
||||||
|
'x-initializer': 'TabPaneInitializers',
|
||||||
|
properties: {
|
||||||
|
tab1: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
title: '{{t("Edit")}}',
|
||||||
|
'x-component': 'Tabs.TabPane',
|
||||||
|
'x-designer': 'Tabs.Designer',
|
||||||
|
'x-component-props': {},
|
||||||
|
properties: {
|
||||||
|
grid: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Grid',
|
||||||
|
'x-initializer': 'RecordBlockInitializers',
|
||||||
|
properties: {
|
||||||
|
dv88ljcl0qw: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Grid.Row',
|
||||||
|
properties: {
|
||||||
|
'548w29v01eb': {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Grid.Col',
|
||||||
|
properties: {
|
||||||
|
q83tzsynghl: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-acl-action-props': {
|
||||||
|
skipScopeCheck: false,
|
||||||
|
},
|
||||||
|
'x-acl-action': 'users:update',
|
||||||
|
'x-decorator': 'FormBlockProvider',
|
||||||
|
'x-decorator-props': {
|
||||||
|
useSourceId: '{{ useSourceIdFromParentRecord }}',
|
||||||
|
useParams: '{{ useParamsFromRecord }}',
|
||||||
|
action: 'get',
|
||||||
|
resource: 'users',
|
||||||
|
collection: 'users',
|
||||||
|
},
|
||||||
|
'x-designer': 'FormV2.Designer',
|
||||||
|
'x-component': 'CardItem',
|
||||||
|
'x-component-props': {},
|
||||||
|
properties: {
|
||||||
|
'8kzqujhwsyl': {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'FormV2',
|
||||||
|
'x-component-props': {
|
||||||
|
useProps: '{{ useFormBlockProps }}',
|
||||||
|
},
|
||||||
|
properties: {
|
||||||
|
grid: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Grid',
|
||||||
|
'x-initializer': 'FormItemInitializers',
|
||||||
|
properties: {
|
||||||
|
'3i87cpmv87x': {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Grid.Row',
|
||||||
|
properties: {
|
||||||
|
am7wls8qu12: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Grid.Col',
|
||||||
|
properties: {
|
||||||
|
roles: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'string',
|
||||||
|
'x-designer': 'FormItem.Designer',
|
||||||
|
'x-component': 'CollectionField',
|
||||||
|
'x-decorator': 'FormItem',
|
||||||
|
'x-collection-field': 'users.roles',
|
||||||
|
'x-component-props': {},
|
||||||
|
'x-uid': 'e196r19yspx',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': 'ato3s57xtbt',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': 'dx3bqu24t50',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': 'rjbjrnn88sq',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 1,
|
||||||
|
},
|
||||||
|
actions: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-initializer': 'UpdateFormActionInitializers',
|
||||||
|
'x-component': 'ActionBar',
|
||||||
|
'x-component-props': {
|
||||||
|
layout: 'one-column',
|
||||||
|
style: {
|
||||||
|
marginTop: 24,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': 'zh8o2drtd9h',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 2,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': 'ytafkst3w0s',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': 'ioqb8wteiwr',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': 'iavf0r5sl2n',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': '994dlhgh1iz',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': 'k390f3n1rz7',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': 'xm264vyzmkf',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': 'asl2rgfrz7p',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': 'xfre469n0yi',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': 'gdjgqvxv6b1',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': 'fnctj4uc8xy',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': '2dc4d3mlw3k',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': '51i2scjmis1',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 2,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': '75owqo6visj',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': 'r4bvdbzinup',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': 'h066j2xouwn',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': 'qrkik5iy790',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': '3vzzy7tipgq',
|
||||||
|
'x-async': true,
|
||||||
|
'x-index': 1,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// fix https://nocobase.height.app/T-2200
|
||||||
|
test('BUG: should be possible to change the value of the association field normally', async ({ page, mockPage }) => {
|
||||||
|
await mockPage(config).goto();
|
||||||
|
|
||||||
|
await page.getByTestId('table-block').getByText('Edit').click();
|
||||||
|
await expect(page.getByTestId('antd-select').getByText('AdminMemberRoot')).toBeVisible();
|
||||||
|
|
||||||
|
await page.getByTestId('antd-select').getByText('AdminMemberRoot').click();
|
||||||
|
await page.getByRole('option', { name: 'Member' }).click();
|
||||||
|
|
||||||
|
// 点击空白处,关闭下拉框。如不关闭,会挡住按钮,导致鼠标 hover 无效
|
||||||
|
await page
|
||||||
|
.getByTestId('action-drawer')
|
||||||
|
.locator('div')
|
||||||
|
.filter({ hasText: 'EditAdd tabRoles:AdminRoot Configure fieldsConfigure actionsAdd block' })
|
||||||
|
.nth(2)
|
||||||
|
.click();
|
||||||
|
|
||||||
|
await expect(page.getByTestId('antd-select').getByText('AdminRoot')).toBeVisible();
|
||||||
|
|
||||||
|
await page.getByTestId('configure-fields-button-of-form-item-users').hover();
|
||||||
|
await page.getByRole('menuitem', { name: 'Nickname' }).click();
|
||||||
|
await page.waitForTimeout(200);
|
||||||
|
await expect(page.getByTestId('antd-select').getByText('AdminRoot')).toBeVisible();
|
||||||
|
});
|
@ -27,8 +27,8 @@ import { HTMLEncode } from '../input/shared';
|
|||||||
import { useColorFields } from '../table-v2/Table.Column.Designer';
|
import { useColorFields } from '../table-v2/Table.Column.Designer';
|
||||||
import { FilterFormDesigner } from './FormItem.FilterFormDesigner';
|
import { FilterFormDesigner } from './FormItem.FilterFormDesigner';
|
||||||
import { useEnsureOperatorsValid } from './SchemaSettingOptions';
|
import { useEnsureOperatorsValid } from './SchemaSettingOptions';
|
||||||
import useLazyLoadDisplayAssociationFieldsOfForm from './hooks/useLazyLoadAssociationFieldOfForm';
|
import useLazyLoadAssociationFieldOfForm from './hooks/useLazyLoadAssociationFieldOfForm';
|
||||||
import useLazyLoadAssociationFieldOfForm from './hooks/useLazyLoadAssociationFieldOfSubForm';
|
import useLazyLoadDisplayAssociationFieldsOfForm from './hooks/useLazyLoadDisplayAssociationFieldsOfForm';
|
||||||
import useParseDefaultValue from './hooks/useParseDefaultValue';
|
import useParseDefaultValue from './hooks/useParseDefaultValue';
|
||||||
|
|
||||||
export const FormItem: any = observer(
|
export const FormItem: any = observer(
|
||||||
|
@ -1,53 +1,66 @@
|
|||||||
import { Field } from '@formily/core';
|
import { Field } from '@formily/core';
|
||||||
import { useField, useFieldSchema, useForm } from '@formily/react';
|
import { useField, useFieldSchema } from '@formily/react';
|
||||||
|
import _ from 'lodash';
|
||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
|
import { useFormBlockType, useRecord } from '../../../..';
|
||||||
import { useCollection, useCollectionManager } from '../../../../collection-manager';
|
import { useCollection, useCollectionManager } from '../../../../collection-manager';
|
||||||
|
import { useFlag } from '../../../../flag-provider';
|
||||||
import { useVariables } from '../../../../variables';
|
import { useVariables } from '../../../../variables';
|
||||||
import { transformVariableValue } from '../../../../variables/utils/transformVariableValue';
|
import { transformVariableValue } from '../../../../variables/utils/transformVariableValue';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用于懒加载 Form 区块中只用于展示的关联字段的值
|
* 用于懒加载 Form 区块中正常的关系字段
|
||||||
*
|
*
|
||||||
* - 在表单区块中,有一个 Display association fields 的选项,这里面的字段,只是为了显示出相应的值,不可更改
|
* - 当 record 中缺少对应的字段值时,通过解析变量的方法去获取关系字段的值
|
||||||
* - 这里就是用于加载这些字段的值
|
* - 注意:应该只有在编辑模式下运行,创建模式下直接返回
|
||||||
*/
|
*/
|
||||||
const useLazyLoadDisplayAssociationFieldsOfForm = () => {
|
const useLazyLoadAssociationFieldOfForm = () => {
|
||||||
const { name } = useCollection();
|
const { name } = useCollection();
|
||||||
const { getCollectionJoinField } = useCollectionManager();
|
const { getCollectionJoinField } = useCollectionManager();
|
||||||
const form = useForm();
|
const record = useRecord();
|
||||||
const fieldSchema = useFieldSchema();
|
const fieldSchema = useFieldSchema();
|
||||||
const variables = useVariables();
|
const variables = useVariables();
|
||||||
const field = useField<Field>();
|
const field = useField<Field>();
|
||||||
|
const { isInAssignFieldValues } = useFlag() || {};
|
||||||
|
const { type: formBlockType } = useFormBlockType();
|
||||||
|
|
||||||
const schemaName = fieldSchema.name.toString();
|
const schemaName = fieldSchema.name.toString();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// 在数据表管理页面,也存在 `a.b` 之类的 schema name,其 collectionName 为 fields,所以在这里排除一下 `name === 'fields'` 的情况
|
if (isInAssignFieldValues || formBlockType === 'create') {
|
||||||
if (!schemaName.includes('.') || !variables || name === 'fields') {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const formVariable = {
|
|
||||||
name: '$nForm',
|
|
||||||
ctx: form.values,
|
|
||||||
collectionName: name,
|
|
||||||
};
|
|
||||||
const variableString = `{{ $nForm.${schemaName} }}`;
|
|
||||||
const collectionField = getCollectionJoinField(`${name}.${schemaName}`);
|
const collectionField = getCollectionJoinField(`${name}.${schemaName}`);
|
||||||
|
|
||||||
if (!collectionField) {
|
if (!collectionField) {
|
||||||
return console.error(new Error(`useLazyLoadAssociationField: ${schemaName} not found in collection ${name}`));
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const cloneRecord = { ...record };
|
||||||
|
delete cloneRecord['__parent'];
|
||||||
|
|
||||||
|
if (_.isEmpty(cloneRecord) || !variables || record[schemaName] != null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 通过模拟一个 record 变量,用解析变量的方法去获取关系字段的值
|
||||||
|
const recordVariable = {
|
||||||
|
name: '$nRecord',
|
||||||
|
ctx: cloneRecord,
|
||||||
|
collectionName: name,
|
||||||
|
};
|
||||||
|
const variableString = `{{ $nRecord.${schemaName} }}`;
|
||||||
|
|
||||||
variables
|
variables
|
||||||
.parseVariable(variableString, formVariable)
|
.parseVariable(variableString, recordVariable)
|
||||||
.then((value) => {
|
.then((value) => {
|
||||||
field.value = transformVariableValue(value, { targetCollectionField: collectionField });
|
field.value = transformVariableValue(value, { targetCollectionField: collectionField });
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
});
|
});
|
||||||
}, [schemaName.includes('.') ? form.values[schemaName.split('.')[0]] : null]);
|
}, []);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default useLazyLoadDisplayAssociationFieldsOfForm;
|
export default useLazyLoadAssociationFieldOfForm;
|
||||||
|
@ -1,66 +0,0 @@
|
|||||||
import { Field } from '@formily/core';
|
|
||||||
import { useField, useFieldSchema } from '@formily/react';
|
|
||||||
import _ from 'lodash';
|
|
||||||
import { useEffect } from 'react';
|
|
||||||
import { useFormBlockType, useRecord } from '../../../..';
|
|
||||||
import { useCollection, useCollectionManager } from '../../../../collection-manager';
|
|
||||||
import { useFlag } from '../../../../flag-provider';
|
|
||||||
import { useVariables } from '../../../../variables';
|
|
||||||
import { transformVariableValue } from '../../../../variables/utils/transformVariableValue';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用于懒加载 Form 区块中正常的关系字段
|
|
||||||
*
|
|
||||||
* - 当 record 中缺少对应的字段值时,通过解析变量的方法去获取关系字段的值
|
|
||||||
* - 注意:应该只有在编辑模式下运行,创建模式下直接返回
|
|
||||||
*/
|
|
||||||
const useLazyLoadAssociationFieldOfForm = () => {
|
|
||||||
const { name } = useCollection();
|
|
||||||
const { getCollectionJoinField } = useCollectionManager();
|
|
||||||
const record = useRecord();
|
|
||||||
const fieldSchema = useFieldSchema();
|
|
||||||
const variables = useVariables();
|
|
||||||
const field = useField<Field>();
|
|
||||||
const { isInAssignFieldValues } = useFlag() || {};
|
|
||||||
const { type: formBlockType } = useFormBlockType();
|
|
||||||
|
|
||||||
const schemaName = fieldSchema.name.toString();
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (isInAssignFieldValues || formBlockType === 'create') {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const collectionField = getCollectionJoinField(`${name}.${schemaName}`);
|
|
||||||
|
|
||||||
if (!collectionField) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const cloneRecord = { ...record };
|
|
||||||
delete cloneRecord['__parent'];
|
|
||||||
|
|
||||||
if (_.isEmpty(cloneRecord) || !variables || record[schemaName] != null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 通过模拟一个 record 变量,用解析变量的方法去获取关系字段的值
|
|
||||||
const recordVariable = {
|
|
||||||
name: '$nRecord',
|
|
||||||
ctx: cloneRecord,
|
|
||||||
collectionName: name,
|
|
||||||
};
|
|
||||||
const variableString = `{{ $nRecord.${schemaName} }}`;
|
|
||||||
|
|
||||||
variables
|
|
||||||
.parseVariable(variableString, recordVariable)
|
|
||||||
.then((value) => {
|
|
||||||
field.value = transformVariableValue(value, { targetCollectionField: collectionField });
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
console.error(err);
|
|
||||||
});
|
|
||||||
}, [field, name, record, schemaName, isInAssignFieldValues]);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default useLazyLoadAssociationFieldOfForm;
|
|
@ -0,0 +1,53 @@
|
|||||||
|
import { Field } from '@formily/core';
|
||||||
|
import { useField, useFieldSchema, useForm } from '@formily/react';
|
||||||
|
import { useEffect } from 'react';
|
||||||
|
import { useCollection, useCollectionManager } from '../../../../collection-manager';
|
||||||
|
import { useVariables } from '../../../../variables';
|
||||||
|
import { transformVariableValue } from '../../../../variables/utils/transformVariableValue';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用于懒加载 Form 区块中只用于展示的关联字段的值
|
||||||
|
*
|
||||||
|
* - 在表单区块中,有一个 Display association fields 的选项,这里面的字段,只是为了显示出相应的值,不可更改
|
||||||
|
* - 这里就是用于加载这些字段的值
|
||||||
|
*/
|
||||||
|
const useLazyLoadDisplayAssociationFieldsOfForm = () => {
|
||||||
|
const { name } = useCollection();
|
||||||
|
const { getCollectionJoinField } = useCollectionManager();
|
||||||
|
const form = useForm();
|
||||||
|
const fieldSchema = useFieldSchema();
|
||||||
|
const variables = useVariables();
|
||||||
|
const field = useField<Field>();
|
||||||
|
|
||||||
|
const schemaName = fieldSchema.name.toString();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
// 在数据表管理页面,也存在 `a.b` 之类的 schema name,其 collectionName 为 fields,所以在这里排除一下 `name === 'fields'` 的情况
|
||||||
|
if (!schemaName.includes('.') || !variables || name === 'fields') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const formVariable = {
|
||||||
|
name: '$nForm',
|
||||||
|
ctx: form.values,
|
||||||
|
collectionName: name,
|
||||||
|
};
|
||||||
|
const variableString = `{{ $nForm.${schemaName} }}`;
|
||||||
|
const collectionField = getCollectionJoinField(`${name}.${schemaName}`);
|
||||||
|
|
||||||
|
if (!collectionField) {
|
||||||
|
return console.error(new Error(`useLazyLoadAssociationField: ${schemaName} not found in collection ${name}`));
|
||||||
|
}
|
||||||
|
|
||||||
|
variables
|
||||||
|
.parseVariable(variableString, formVariable)
|
||||||
|
.then((value) => {
|
||||||
|
field.value = transformVariableValue(value, { targetCollectionField: collectionField });
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.error(err);
|
||||||
|
});
|
||||||
|
}, [schemaName.includes('.') ? form.values[schemaName.split('.')[0]] : null]);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default useLazyLoadDisplayAssociationFieldsOfForm;
|
Loading…
Reference in New Issue
Block a user