diff --git a/packages/core/client/src/schema-component/antd/action/Action.tsx b/packages/core/client/src/schema-component/antd/action/Action.tsx
index bc03713be..b23c1e8b5 100644
--- a/packages/core/client/src/schema-component/antd/action/Action.tsx
+++ b/packages/core/client/src/schema-component/antd/action/Action.tsx
@@ -66,6 +66,7 @@ export const Action: ComposedAction = observer(
let actionTitle = title || compile(fieldSchema.title);
actionTitle = lodash.isString(actionTitle) ? t(actionTitle) : actionTitle;
useEffect(() => {
+ field.linkageProperty = {};
linkageRules
.filter((k) => !k.disabled)
.forEach((v) => {
diff --git a/packages/core/client/src/schema-component/antd/action/utils.ts b/packages/core/client/src/schema-component/antd/action/utils.ts
index c43e27eea..3d282019a 100644
--- a/packages/core/client/src/schema-component/antd/action/utils.ts
+++ b/packages/core/client/src/schema-component/antd/action/utils.ts
@@ -1,7 +1,9 @@
import type { ISchema } from '@formily/react';
+import { last } from 'lodash';
import { ActionType } from '../../../schema-settings/LinkageRules/type';
import { VariableOption, VariablesContextType } from '../../../variables/types';
import { conditionAnalyses } from '../../common/utils/uitls';
+
const validateJSON = {
validator: `{{(value, rule)=> {
if (!value) {
@@ -84,54 +86,52 @@ export const linkageAction = async ({
variables: VariablesContextType;
localVariables: VariableOption[];
}) => {
- field.data = field.data || {};
+ const disableResult = field?.linkageProperty?.disabled || [false];
+ const displayResult = field?.linkageProperty?.display || ['visible'];
switch (operator) {
case ActionType.Visible:
- reset(field);
if (await conditionAnalyses({ rules: condition, formValues: values, variables, localVariables })) {
- field._display = '_display' in field ? field._display : field.display;
- field.display = operator;
- } else {
- field.display = field._display;
+ displayResult.push(operator);
+ field.data = field.data || {};
+ field.data.hidden = false;
}
+ field.linkageProperty = {
+ ...field.linkageProperty,
+ display: displayResult,
+ };
+ field.display = last(displayResult);
break;
case ActionType.Hidden:
- reset(field);
if (await conditionAnalyses({ rules: condition, formValues: values, variables, localVariables })) {
+ field.data = field.data || {};
field.data.hidden = true;
} else {
+ field.data = field.data || {};
field.data.hidden = false;
}
break;
case ActionType.Disabled:
- reset(field);
if (await conditionAnalyses({ rules: condition, formValues: values, variables, localVariables })) {
- field.data.disabled = true;
- field.disabled = true;
- } else {
- field.data.disabled = false;
- field.disabled = false;
+ disableResult.push(true);
}
+ field.linkageProperty = {
+ ...field.linkageProperty,
+ disabled: disableResult,
+ };
+ field.disabled = last(disableResult);
break;
case ActionType.Active:
- reset(field);
if (await conditionAnalyses({ rules: condition, formValues: values, variables, localVariables })) {
- field.data.disabled = false;
- field.disabled = false;
- } else {
- field.data.disabled = true;
- field.disabled = true;
+ disableResult.push(false);
}
+ field.linkageProperty = {
+ ...field.linkageProperty,
+ disabled: disableResult,
+ };
+ field.disabled = last(disableResult);
break;
default:
return null;
}
};
-
-function reset(field: any) {
- field.display = field._display;
- field.data.hidden = false;
- field.data.disabled = false;
- field.disabled = false;
-}
diff --git a/packages/core/client/src/schema-component/antd/form-v2/Form.tsx b/packages/core/client/src/schema-component/antd/form-v2/Form.tsx
index 2558c8370..35f048005 100644
--- a/packages/core/client/src/schema-component/antd/form-v2/Form.tsx
+++ b/packages/core/client/src/schema-component/antd/form-v2/Form.tsx
@@ -1,6 +1,6 @@
import { css } from '@emotion/css';
import { FormLayout } from '@formily/antd-v5';
-import { createForm, Field, Form as FormilyForm, onFieldInit, onFormInputChange } from '@formily/core';
+import { createForm, Field, Form as FormilyForm, onFieldChange, onFieldInit, onFormInputChange } from '@formily/core';
import { FieldContext, FormContext, observer, RecursionField, useField, useFieldSchema } from '@formily/react';
import { autorun } from '@formily/reactive';
import { uid } from '@formily/shared';
@@ -103,31 +103,32 @@ const WithForm = (props: WithFormProps) => {
useEffect(() => {
const id = uid();
const disposes = [];
+ const linkagefields = [];
form.addEffects(id, () => {
- linkageRules.forEach((v) => {
+ linkageRules.forEach((v, index) => {
v.actions?.forEach((h) => {
if (h.targetFields?.length) {
const fields = h.targetFields.join(',');
-
- // 当 `linkageRules` 变更时,需要把 `field` 上之前已设置的值还原成初始值,以防止下面所述的情况:
- //
- // 1. 更改 `linkageRules`,使 a 字段满足条件时被隐藏
- // 2. 设置表单,使其满足条件,进而隐藏 a 字段
- // 3. 再次更改 `linkageRules`,使 a 字段满足条件时被禁用
- // 4. 设置表单,使其满足条件,会发现 a 字段还是隐藏状态,这里期望的是只显示禁用状态
- onFieldInit(`*(${fields})`, (field: any) => {
- Object.keys(field).forEach((key) => {
- if (key.startsWith('_') && field[key] !== undefined) {
- field[key.slice(1)] = field[key];
- }
- });
+ onFieldInit(`*(${fields})`, (field: any, form) => {
+ field['initProperty'] = {
+ display: field.display,
+ required: field.required,
+ pattern: field.pattern,
+ value: field.value || field.initialValue,
+ };
+ });
+ onFieldChange(`*(${fields})`, ['value', 'required', 'pattern', 'display'], (field: any) => {
+ field.linkageProperty = {
+ display: field.linkageProperty?.display,
+ };
});
// `onFieldReact` 有问题,没有办法被取消监听,所以这里用 `onFieldInit` 代替
onFieldInit(`*(${fields})`, (field: any, form) => {
disposes.push(
autorun(() => {
+ linkagefields.push(field);
linkageMergeAction({
operator: h.operator,
value: h.value,
@@ -137,6 +138,13 @@ const WithForm = (props: WithFormProps) => {
variables,
localVariables,
});
+ if (index === linkageRules.length - 1) {
+ setTimeout(() =>
+ linkagefields.map((v) => {
+ v.linkageProperty = {};
+ }),
+ );
+ }
}),
);
});
@@ -151,7 +159,7 @@ const WithForm = (props: WithFormProps) => {
dispose();
});
};
- }, [JSON.stringify(linkageRules)]);
+ }, [linkageRules]);
return fieldSchema['x-decorator'] === 'FormV2' ? : ;
};
diff --git a/packages/core/client/src/schema-component/antd/form-v2/utils.tsx b/packages/core/client/src/schema-component/antd/form-v2/utils.tsx
index f21b60437..c7b5e79aa 100644
--- a/packages/core/client/src/schema-component/antd/form-v2/utils.tsx
+++ b/packages/core/client/src/schema-component/antd/form-v2/utils.tsx
@@ -1,7 +1,7 @@
import { Field } from '@formily/core';
import { evaluators } from '@nocobase/evaluators/client';
import { uid } from '@nocobase/utils';
-import _, { cloneDeep } from 'lodash';
+import _, { cloneDeep, last } from 'lodash';
import { ActionType } from '../../../schema-settings/LinkageRules/type';
import { VariableOption, VariablesContextType } from '../../../variables/types';
import { REGEX_OF_VARIABLE } from '../../../variables/utils/isVariable';
@@ -28,47 +28,62 @@ export const linkageMergeAction = async ({
variables,
localVariables,
}: Props) => {
+ const requiredResult = field?.linkageProperty?.required || [field?.initProperty?.required || false];
+ const displayResult = field?.linkageProperty?.display || [field?.initProperty?.display];
+ const patternResult = field?.linkageProperty?.pattern || [field?.initProperty?.pattern];
+ const valueResult = field?.linkageProperty?.value || [field.value || field?.initProperty?.value];
const { evaluate } = evaluators.get('formula.js');
switch (operator) {
case ActionType.Required:
if (await conditionAnalyses({ rules: condition, formValues: values, variables, localVariables })) {
- field.required = true;
- } else {
- field.required = false;
+ requiredResult.push(true);
}
+ field.linkageProperty = {
+ ...field.linkageProperty,
+ required: requiredResult,
+ };
+ field.required = last(field.linkageProperty?.required);
break;
case ActionType.InRequired:
if (await conditionAnalyses({ rules: condition, formValues: values, variables, localVariables })) {
- field.required = false;
- } else {
- field.required = true;
+ requiredResult.push(false);
}
+ field.linkageProperty = {
+ ...field.linkageProperty,
+ required: requiredResult,
+ };
+ field.required = last(field.linkageProperty?.required);
break;
case ActionType.Visible:
case ActionType.None:
case ActionType.Hidden:
if (await conditionAnalyses({ rules: condition, formValues: values, variables, localVariables })) {
- field._display = '_display' in field ? field._display : field.display;
- field.display = operator;
+ displayResult.push(operator);
}
+ field.linkageProperty = {
+ ...field.linkageProperty,
+ display: displayResult,
+ };
+ field.display = last(field.linkageProperty?.display);
break;
case ActionType.Editable:
case ActionType.ReadOnly:
case ActionType.ReadPretty:
if (await conditionAnalyses({ rules: condition, formValues: values, variables, localVariables })) {
- field._pattern = '_pattern' in field ? field._pattern : field.pattern;
- field.pattern = operator;
- } else {
- field.pattern = field._pattern;
+ patternResult.push(operator);
}
+ field.linkageProperty = {
+ ...field.linkageProperty,
+ pattern: patternResult,
+ };
+ field.pattern = last(field.linkageProperty.pattern);
break;
case ActionType.Value:
if (
isConditionEmpty(condition) ||
(await conditionAnalyses({ rules: condition, formValues: values, variables, localVariables }))
) {
- let result = null;
if (value?.mode === 'express') {
if ((value.value || value.result) == null) {
return;
@@ -84,19 +99,22 @@ export const linkageMergeAction = async ({
try {
// 2. TODO: 需要把里面解析变量的逻辑删除,因为在上一步已经解析过了
- result = evaluate(exp, { ...scope, now: () => new Date().toString(), ...expScope });
+ const result = evaluate(exp, { ...scope, now: () => new Date().toString(), ...expScope });
+ valueResult.push(result);
} catch (error) {
console.error(error);
}
} else if (value?.mode === 'constant') {
- result = value?.value || value;
+ valueResult.push(value?.value || value);
} else {
- result = null;
+ valueResult.push(null);
}
- field._value = '_value' in field ? field._value : field.value;
- field.value = result === undefined ? field.value : result;
- } else {
- field.value = field._value;
+
+ field.linkageProperty = {
+ ...field.linkageProperty,
+ value: valueResult,
+ };
+ field.value = last(valueResult) === undefined ? field.value : last(valueResult);
}
break;
default:
diff --git a/packages/core/client/src/schema-initializer/components/CreateRecordAction.tsx b/packages/core/client/src/schema-initializer/components/CreateRecordAction.tsx
index 3d5cd54ad..66c31c724 100644
--- a/packages/core/client/src/schema-initializer/components/CreateRecordAction.tsx
+++ b/packages/core/client/src/schema-initializer/components/CreateRecordAction.tsx
@@ -97,6 +97,7 @@ export const CreateRecordAction = observer(
const localVariables = useLocalVariables({ currentForm: { values } as any });
useEffect(() => {
+ field.linkageProperty = {};
linkageRules
.filter((k) => !k.disabled)
.forEach((v) => {
@@ -201,6 +202,7 @@ export const CreateAction = observer(
}, [menuItems]);
useEffect(() => {
+ field.linkageProperty = {};
linkageRules
.filter((k) => !k.disabled)
.forEach((v) => {