From 1bc31d5fd30191dd535810e97fd6eedafa2c36e5 Mon Sep 17 00:00:00 2001 From: jialan Date: Thu, 7 Dec 2023 11:37:32 +0800 Subject: [PATCH 1/2] fix(core): recalculate valueDerived when values changed --- .../src/components/formItemWrapper/index.tsx | 29 +++++----------- .../src/components/formRenderer/index.tsx | 34 ++++++++++++++++++- 2 files changed, 41 insertions(+), 22 deletions(-) diff --git a/packages/core/src/components/formItemWrapper/index.tsx b/packages/core/src/components/formItemWrapper/index.tsx index 57134d2..17c03c6 100644 --- a/packages/core/src/components/formItemWrapper/index.tsx +++ b/packages/core/src/components/formItemWrapper/index.tsx @@ -1,9 +1,9 @@ import React, { useContext, useEffect, useMemo } from 'react'; -import { Form, FormInstance, Col } from 'antd'; +import { Form, Col } from 'antd'; import { debounce } from '../helpers'; import ExtraContext from '../../extraDataContext'; import internalWidgets from '../internalWidgets'; -import type { ScopeType } from '../../expressionParser/fnExpressionTransformer'; +import type { TransformedFnType } from '../../expressionParser/fnExpressionTransformer'; import PubSubCenter from '../../interaction/pubSubCenter'; import { FieldItemMetaType, @@ -20,6 +20,10 @@ export interface FormItemWrapperProps { formItemMeta: FieldItemMetaType; defaultSpan?: number; getWidgets: GetWidgets; + calcDerivedValue: ( + fieldName: string, + valueDerived: TransformedFnType + ) => void; publishServiceEvent: PubSubCenter['publishServiceEvent']; onDerivedValueChange: (fieldName: string, value: any) => any; valueGetter: (value) => any; @@ -34,7 +38,7 @@ const FormItemWrapper: React.FC = (props) => { publishServiceEvent, valueGetter, debounceSearch, - onDerivedValueChange, + calcDerivedValue, } = props; const { fieldName, @@ -81,23 +85,6 @@ const FormItemWrapper: React.FC = (props) => { } }, []); - /** - * 处理派生值的情况 - */ - const deriveValue = (form: FormInstance) => { - if (valueDerived === null) return; - - const scope: ScopeType = { - formData: form.getFieldsValue(), - extraDataRef: extraContext.extraDataRef, - }; - const derivedValue = valueDerived(scope); - if (derivedValue !== form.getFieldValue(fieldName)) { - form.setFieldValue(fieldName, derivedValue); - onDerivedValueChange(fieldName, derivedValue); - } - }; - const getServiceTriggerProps = (formData, extraData) => { const serviceTriggerProps = { onBlur: null, @@ -157,7 +144,7 @@ const FormItemWrapper: React.FC = (props) => { {(form) => { if (valueGetter(destroy)) return null; - deriveValue(form as FormInstance); + calcDerivedValue(fieldName, valueDerived); const { onBlur, onFocus, onSearch } = getServiceTriggerProps( form.getFieldsValue(), extraContext.extraDataRef diff --git a/packages/core/src/components/formRenderer/index.tsx b/packages/core/src/components/formRenderer/index.tsx index eedddac..a8ee45f 100644 --- a/packages/core/src/components/formRenderer/index.tsx +++ b/packages/core/src/components/formRenderer/index.tsx @@ -21,7 +21,10 @@ import ExtraContext, { useExtraData } from '../../extraDataContext'; import JsonConfigTransformer from '../../expressionParser/jsonConfigTransformer'; import PubSubCenter from '../../interaction/pubSubCenter'; import InteractionSubscriber from '../../interaction/interactionSubscriber'; -import type { ScopeType } from '../../expressionParser/fnExpressionTransformer'; +import type { + ScopeType, + TransformedFnType, +} from '../../expressionParser/fnExpressionTransformer'; const { useForm } = Form; @@ -142,6 +145,26 @@ const FormRenderer: React.ForwardRefRenderFunction< } }; + /** + * 处理派生值的情况 + */ + const calcDerivedValue = ( + fieldName: string, + valueDerived: TransformedFnType + ) => { + if (valueDerived === null) return; + + const scope: ScopeType = { + formData: form.getFieldsValue(), + extraDataRef: extraDataRef, + }; + const derivedValue = valueDerived(scope); + if (derivedValue !== form.getFieldValue(fieldName)) { + form.setFieldValue(fieldName, derivedValue); + onDerivedValueChange(fieldName, derivedValue); + } + }; + const onValuesChange = (changedValues, _values) => { const changedFields = Object.keys(changedValues); let interactFields = []; @@ -153,6 +176,14 @@ const FormRenderer: React.ForwardRefRenderFunction< interactFields = [...interactFields, ...fieldsName]; }); + const derivedValueFields = formItemsMeta.filter( + (item) => item.valueDerived !== null + ); + + derivedValueFields.forEach((item) => { + calcDerivedValue(item.fieldName, item.valueDerived); + }); + const shouldRenderFields = formItemsMeta .filter((item) => { return !valueGetter(item.destroy); @@ -213,6 +244,7 @@ const FormRenderer: React.ForwardRefRenderFunction< defaultSpan={defaultColSpan} key={formItemMeta.fieldName} formItemMeta={formItemMeta} + calcDerivedValue={calcDerivedValue} onDerivedValueChange={onDerivedValueChange} publishServiceEvent={ pubSubCenterRef.current.publishServiceEvent From 87873a765dba460644ab96583bf4030f6d6618e9 Mon Sep 17 00:00:00 2001 From: jialan Date: Thu, 7 Dec 2023 16:17:28 +0800 Subject: [PATCH 2/2] fix(core): catch function expression transform errors --- .../src/expressionParser/fnExpressionTransformer.ts | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/packages/core/src/expressionParser/fnExpressionTransformer.ts b/packages/core/src/expressionParser/fnExpressionTransformer.ts index 9419eb8..8d9240f 100644 --- a/packages/core/src/expressionParser/fnExpressionTransformer.ts +++ b/packages/core/src/expressionParser/fnExpressionTransformer.ts @@ -1,3 +1,4 @@ +import { warning } from '../utils/report'; import { ExtraDataRefType } from '../extraDataContext'; export interface ScopeType { @@ -42,8 +43,15 @@ class FnExpressionTransformer { return (scope: ScopeType) => { const proxy = this.createProxy(scope); const fnBody = `with(scope) { return ${code} }`; - const fn = new Function('scope', fnBody); - return fn(proxy); + try { + const fn = new Function('scope', fnBody); + return fn(proxy); + } catch (error) { + warning( + `The function expression transform failed: "${code}". ErrorMessage: ${error}`, + 'Expression' + ); + } }; }; }