From a97bf77ee634900b03491d15020fe6a9b3801ffe Mon Sep 17 00:00:00 2001 From: 2betop <2698393+2betop@users.noreply.github.com> Date: Thu, 19 Sep 2024 20:11:03 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E9=9A=90=E8=97=8F=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E4=B8=AD=E6=B7=BB=E5=8A=A0=20=5F=5FchangeReason=20=E5=AD=97?= =?UTF-8?q?=E6=AE=B5=E5=B9=B6=E8=A1=A5=E5=85=85=E6=96=87=E6=A1=A3=E8=AF=B4?= =?UTF-8?q?=E6=98=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../zh-CN/concepts/datascope-and-datachain.md | 75 +++++++++++++++++++ packages/amis-core/src/WithStore.tsx | 21 ++++-- packages/amis-core/src/renderers/Form.tsx | 41 ++++++++-- packages/amis-core/src/renderers/Item.tsx | 4 +- .../amis-core/src/renderers/wrapControl.tsx | 58 ++++++++++++-- packages/amis-core/src/store/form.ts | 41 ++++++++-- packages/amis-core/src/store/iRenderer.ts | 40 +++++++++- packages/amis-core/src/store/service.ts | 15 +++- packages/amis-core/src/types.ts | 29 +++++++ packages/amis-editor-core/src/plugin.ts | 2 +- packages/amis-editor-core/src/store/editor.ts | 6 +- packages/amis-editor-core/src/util.ts | 4 +- packages/amis-editor/src/plugin/Dialog.tsx | 2 +- .../src/renderer/FormulaControl.tsx | 2 +- .../src/renderer/StatusControl.tsx | 2 +- .../event-control/DialogActionPanel.tsx | 2 +- .../src/renderer/event-control/index.tsx | 2 +- packages/amis-editor/src/tpl/common.tsx | 2 +- .../__tests__/renderers/CRUDfilter.test.tsx | 2 +- packages/amis/src/renderers/Service.tsx | 4 +- packages/amis/src/types.ts | 14 ++++ 21 files changed, 320 insertions(+), 48 deletions(-) diff --git a/docs/zh-CN/concepts/datascope-and-datachain.md b/docs/zh-CN/concepts/datascope-and-datachain.md index a4042e859..9c3be10d2 100755 --- a/docs/zh-CN/concepts/datascope-and-datachain.md +++ b/docs/zh-CN/concepts/datascope-and-datachain.md @@ -456,3 +456,78 @@ url 中的参数会进入顶层数据域,比如下面的例子,可以点击[ "body": "${word}" } ``` + +## 隐藏数据 + +数据中还有以下字段不会被枚举到,但是可以读取: + +- `__prev` 修改前的值 +- `__changeReason` 修改原因 +- `__changeReason.type` 修改原因类型 + - `input` 用户输入 + - `api` api 接口返回触发 + - `formula` 公式计算触发 + - `hide` 隐藏属性变化触发 + - `init` 表单项初始化触发 + - `action` 事件动作触发 +- `__super` 数据链的上一级 + +> `__changeReason` 字段在 amis 6.9.0 版本开始支持 + +```schema +{ + "data": { + "name": "amis" + }, + "type": "form", + id: "form_data", + "actions": [ + { + type: "button", + label: "接口获取", + actionType: "ajax", + api: { + "method": "get", + url: "/api/mock2/form/saveForm", + mockResponse: { + status: 200, + data: { + name: "amis-demo" + } + } + } + }, + + { + type: "button", + label: "设置值", + onEvent: { + click: { + actions: [ + { + "actionType": "setValue", + "componentId": "form_data", + "args": { + "value": { + "name": "amis-demo2" + } + } + } + ] + } + } + }, + ], + "body": [ + { + type: "input-text", + name: "name", + label: "姓名" + }, + { + type: "tpl", + tpl: "当前值:${name}
修改前的值:${__prev.name}
变化原因:${__changeReason|json}" + } + ] +} +``` diff --git a/packages/amis-core/src/WithStore.tsx b/packages/amis-core/src/WithStore.tsx index 057e5643a..8b520770c 100644 --- a/packages/amis-core/src/WithStore.tsx +++ b/packages/amis-core/src/WithStore.tsx @@ -258,7 +258,8 @@ export function HocStoreFactory(renderer: { ...this.formatData(props.data) }), (props.updatePristineAfterStoreDataReInit ?? - props.dataUpdatedAt !== prevProps.dataUpdatedAt) === false + props.dataUpdatedAt !== prevProps.dataUpdatedAt) === false, + props.data?.__changeReason ); } } else if ( @@ -293,7 +294,9 @@ export function HocStoreFactory(renderer: { )) }), (props.updatePristineAfterStoreDataReInit ?? - props.dataUpdatedAt !== prevProps.dataUpdatedAt) === false + props.dataUpdatedAt !== prevProps.dataUpdatedAt) === false, + + props.data?.__changeReason ); } else if (props.data && (props.data as any).__super) { store.initData( @@ -325,13 +328,15 @@ export function HocStoreFactory(renderer: { )) }), (props.updatePristineAfterStoreDataReInit ?? - props.dataUpdatedAt !== prevProps.dataUpdatedAt) === false + props.dataUpdatedAt !== prevProps.dataUpdatedAt) === false, + props.data?.__changeReason ); } else { store.initData( createObject(props.scope, props.data), (props.updatePristineAfterStoreDataReInit ?? - props.dataUpdatedAt !== prevProps.dataUpdatedAt) === false + props.dataUpdatedAt !== prevProps.dataUpdatedAt) === false, + props.data?.__changeReason ); } } else if ( @@ -358,7 +363,9 @@ export function HocStoreFactory(renderer: { (props.updatePristineAfterStoreDataReInit ?? props.dataUpdatedAt !== prevProps.dataUpdatedAt) === false || (store.storeType === 'FormStore' && - prevProps.store?.storeType === 'CRUDStore') + prevProps.store?.storeType === 'CRUDStore'), + + props.data?.__changeReason ); } // nextProps.data.__super !== props.data.__super) && @@ -376,7 +383,9 @@ export function HocStoreFactory(renderer: { ...store.data }), (props.updatePristineAfterStoreDataReInit ?? - props.dataUpdatedAt !== prevProps.dataUpdatedAt) === false + props.dataUpdatedAt !== prevProps.dataUpdatedAt) === false, + + props.data?.__changeReason ); } } diff --git a/packages/amis-core/src/renderers/Form.tsx b/packages/amis-core/src/renderers/Form.tsx index 5a24a34aa..1eb78a1e3 100644 --- a/packages/amis-core/src/renderers/Form.tsx +++ b/packages/amis-core/src/renderers/Form.tsx @@ -11,7 +11,8 @@ import { ClassName, BaseApiObject, SchemaExpression, - SchemaClassName + SchemaClassName, + DataChangeReason } from '../types'; import {filter, evalExpression} from '../utils/tpl'; import getExprProperties from '../utils/filter-schema'; @@ -633,7 +634,9 @@ export default class Form extends React.Component { successMessage: fetchSuccess, errorMessage: fetchFailed, onSuccess: (json: Payload, data: any) => { - store.setValues(data); + store.setValues(data, undefined, undefined, undefined, { + type: 'api' + }); if ( !isEffectiveApi(initAsyncApi, store.data) || @@ -968,7 +971,9 @@ export default class Form extends React.Component { setValues(value: any, replace?: boolean) { const {store} = this.props; this.flush(); - store.setValues(value, undefined, replace); + store.setValues(value, undefined, replace, undefined, { + type: 'action' + }); } async submit( @@ -1056,13 +1061,23 @@ export default class Form extends React.Component { value: any, name: string, submit: boolean, - changePristine = false + changePristine = false, + changeReason?: DataChangeReason ) { const {store, formLazyChange, persistDataKeys} = this.props; if (typeof name !== 'string') { return; } - store.changeValue(name, value, changePristine); + store.changeValue( + name, + value, + changePristine, + undefined, + undefined, + changeReason || { + type: 'input' + } + ); if (!changePristine || typeof value !== 'undefined') { (formLazyChange === false ? this.emitChange : this.lazyEmitChange)( submit @@ -1131,9 +1146,21 @@ export default class Form extends React.Component { } } - handleBulkChange(values: Object, submit: boolean) { + handleBulkChange( + values: Object, + submit: boolean, + changeReason?: DataChangeReason + ) { const {onChange, store, formLazyChange} = this.props; - store.setValues(values); + store.setValues( + values, + undefined, + undefined, + undefined, + changeReason || { + type: 'input' + } + ); // store.updateData(values); // store.items.forEach(formItem => { diff --git a/packages/amis-core/src/renderers/Item.tsx b/packages/amis-core/src/renderers/Item.tsx index c6e51e6c4..9fa8f0b69 100644 --- a/packages/amis-core/src/renderers/Item.tsx +++ b/packages/amis-core/src/renderers/Item.tsx @@ -27,6 +27,7 @@ import { BaseApiObject, BaseSchemaWithoutType, ClassName, + DataChangeReason, Schema } from '../types'; import {HocStoreFactory} from '../WithStore'; @@ -530,7 +531,8 @@ export interface FormItemProps extends RendererProps { ) => void; onBulkChange?: ( values: {[propName: string]: any}, - submitOnChange?: boolean + submitOnChange?: boolean, + changeReason?: DataChangeReason ) => void; addHook: ( fn: Function, diff --git a/packages/amis-core/src/renderers/wrapControl.tsx b/packages/amis-core/src/renderers/wrapControl.tsx index 090349f0e..ef5ccdd1f 100644 --- a/packages/amis-core/src/renderers/wrapControl.tsx +++ b/packages/amis-core/src/renderers/wrapControl.tsx @@ -28,7 +28,7 @@ import {observer} from 'mobx-react'; import hoistNonReactStatic from 'hoist-non-react-statics'; import {withRootStore} from '../WithRootStore'; import {FormBaseControl, FormItemWrap} from './Item'; -import {Api} from '../types'; +import {Api, DataChangeReason} from '../types'; import {TableStore} from '../store/table'; import pick from 'lodash/pick'; import { @@ -75,14 +75,19 @@ export interface ControlOutterProps extends RendererProps { value: any, name: string, submit?: boolean, - changePristine?: boolean + changePristine?: boolean, + changeReason?: DataChangeReason ) => void; formItemDispatchEvent: (type: string, data: any) => void; formItemRef?: (control: any) => void; } export interface ControlProps { - onBulkChange?: (values: Object) => void; + onBulkChange?: ( + values: Object, + submitOnChange?: boolean, + changeReason?: DataChangeReason + ) => void; onChange?: (value: any, name: string, submit: boolean) => void; store: IIRendererStore; } @@ -535,7 +540,9 @@ export function wrapControl< formItem.removeSubFormItem(this.model); this.model.clearValueOnHidden && - this.model.form?.deleteValueByName(this.model.name); + this.model.form?.deleteValueByName(this.model.name, { + type: 'hide' + }); isAlive(rootStore) && rootStore.removeStore(this.model); } @@ -691,7 +698,10 @@ export function wrapControl< ); } - this.model.changeTmpValue(value, 'input'); + this.model.changeTmpValue( + value, + type === 'formula' ? 'formulaChanged' : 'input' + ); if (changeImmediately || conrolChangeImmediately || !formInited) { this.emitChange(submitOnChange); @@ -772,12 +782,44 @@ export function wrapControl< return; } + const changeReason: DataChangeReason = { + type: 'input' + }; + + if (model.changeMotivation === 'formulaChanged') { + changeReason.type = 'formula'; + } else if ( + model.changeMotivation === 'initialValue' || + model.changeMotivation === 'formInited' || + model.changeMotivation === 'defaultValue' + ) { + changeReason.type = 'init'; + } + if (model.extraName) { const values = model.splitExtraValue(value); - onChange?.(values[0], model.name); - onChange?.(values[1], model.extraName, submitOnChange === true); + onChange?.( + values[0], + model.name, + undefined, + undefined, + changeReason + ); + onChange?.( + values[1], + model.extraName, + submitOnChange === true, + undefined, + changeReason + ); } else { - onChange?.(value, model.name, submitOnChange === true); + onChange?.( + value, + model.name, + submitOnChange === true, + undefined, + changeReason + ); } this.checkValidate(); } diff --git a/packages/amis-core/src/store/form.ts b/packages/amis-core/src/store/form.ts index 617248073..c675ebea7 100644 --- a/packages/amis-core/src/store/form.ts +++ b/packages/amis-core/src/store/form.ts @@ -5,7 +5,13 @@ import toPairs from 'lodash/toPairs'; import pick from 'lodash/pick'; import {ServiceStore} from './service'; import type {IFormItemStore} from './formItem'; -import {Api, ApiObject, fetchOptions, Payload} from '../types'; +import { + Api, + ApiObject, + DataChangeReason, + fetchOptions, + Payload +} from '../types'; import {ServerError} from '../utils/errors'; import { getVariable, @@ -168,9 +174,10 @@ export const FormStore = ServiceStore.named('FormStore') values: object, tag?: object, replace?: boolean, - concatFields?: string | string[] + concatFields?: string | string[], + changeReason?: DataChangeReason ) { - self.updateData(values, tag, replace, concatFields); + self.updateData(values, tag, replace, concatFields, changeReason); // 如果数据域中有数据变化,就都reset一下,去掉之前残留的验证消息 self.items.forEach(item => { @@ -209,7 +216,8 @@ export const FormStore = ServiceStore.named('FormStore') name: string, value: any, isPristine: boolean = false, - force: boolean = false + force: boolean = false, + changeReason?: DataChangeReason ) { // 没有变化就不跑了。 const origin = getVariable(self.data, name, false); @@ -257,13 +265,22 @@ export const FormStore = ServiceStore.named('FormStore') }); } + changeReason && + Object.isExtensible(data) && + Object.defineProperty(data, '__changeReason', { + value: changeReason, + enumerable: false, + configurable: false, + writable: false + }); + self.data = data; // 同步 options syncOptions(); } - function deleteValueByName(name: string) { + function deleteValueByName(name: string, changeReason?: DataChangeReason) { const prev = self.data; const data = cloneObject(self.data); @@ -287,6 +304,15 @@ export const FormStore = ServiceStore.named('FormStore') } deleteVariable(data, name); + + changeReason && + Object.isExtensible(data) && + Object.defineProperty(data, '__changeReason', { + value: changeReason, + enumerable: false, + configurable: false, + writable: false + }); self.data = data; } @@ -374,7 +400,10 @@ export const FormStore = ServiceStore.named('FormStore') } : undefined, !!(api as ApiObject).replaceData, - (api as ApiObject).concatDataFields + (api as ApiObject).concatDataFields, + { + type: 'api' + } ); } diff --git a/packages/amis-core/src/store/iRenderer.ts b/packages/amis-core/src/store/iRenderer.ts index dad28c5a1..741660fd7 100644 --- a/packages/amis-core/src/store/iRenderer.ts +++ b/packages/amis-core/src/store/iRenderer.ts @@ -18,6 +18,7 @@ import { extractObjectChain, injectObjectChain } from '../utils'; +import {DataChangeReason} from '../types'; export const iRendererStore = StoreNode.named('iRendererStore') .props({ @@ -66,7 +67,11 @@ export const iRendererStore = StoreNode.named('iRendererStore') top = value; }, - initData(data: object = {}, skipSetPristine = false) { + initData( + data: object = {}, + skipSetPristine = false, + changeReason?: DataChangeReason + ) { self.initedAt = Date.now(); if (self.data.__tag) { @@ -78,6 +83,15 @@ export const iRendererStore = StoreNode.named('iRendererStore') self.pristineRaw = data; } + changeReason && + Object.isExtensible(data) && + Object.defineProperty(data, '__changeReason', { + value: changeReason, + enumerable: false, + configurable: false, + writable: false + }); + self.data = data; self.upStreamData = data; }, @@ -90,7 +104,8 @@ export const iRendererStore = StoreNode.named('iRendererStore') data: object = {}, tag?: object, replace?: boolean, - concatFields?: string | string[] + concatFields?: string | string[], + changeReason?: DataChangeReason ) { if (concatFields) { data = concatData(data, self.data, concatFields); @@ -118,6 +133,15 @@ export const iRendererStore = StoreNode.named('iRendererStore') writable: false }); + changeReason && + Object.isExtensible(newData) && + Object.defineProperty(newData, '__changeReason', { + value: changeReason, + enumerable: false, + configurable: false, + writable: false + }); + self.data = newData; }, @@ -126,7 +150,8 @@ export const iRendererStore = StoreNode.named('iRendererStore') value: any, changePristine?: boolean, force?: boolean, - otherModifier?: (data: Object) => void + otherModifier?: (data: Object) => void, + changeReason?: DataChangeReason ) { if (!name) { return; @@ -183,6 +208,15 @@ export const iRendererStore = StoreNode.named('iRendererStore') }); } + changeReason && + Object.isExtensible(data) && + Object.defineProperty(data, '__changeReason', { + value: changeReason, + enumerable: false, + configurable: false, + writable: false + }); + self.data = data; }, diff --git a/packages/amis-core/src/store/service.ts b/packages/amis-core/src/store/service.ts index 70b46d0a9..9f8c82702 100644 --- a/packages/amis-core/src/store/service.ts +++ b/packages/amis-core/src/store/service.ts @@ -202,7 +202,10 @@ export const ServiceStore = iRendererStore normalizeApiResponseData(json.data), undefined, !!(api as ApiObject).replaceData, - (api as ApiObject).concatDataFields + (api as ApiObject).concatDataFields, + { + type: 'api' + } ); self.hasRemoteData = true; @@ -301,7 +304,10 @@ export const ServiceStore = iRendererStore normalizeApiResponseData(json.data), undefined, !!(api as ApiObject).replaceData, - (api as ApiObject).concatDataFields + (api as ApiObject).concatDataFields, + { + type: 'api' + } ); } @@ -471,7 +477,10 @@ export const ServiceStore = iRendererStore json.data.data, undefined, !!(api as ApiObject).replaceData, - (api as ApiObject).concatDataFields + (api as ApiObject).concatDataFields, + { + type: 'api' + } ); } diff --git a/packages/amis-core/src/types.ts b/packages/amis-core/src/types.ts index e95954a9a..5f4458bec 100644 --- a/packages/amis-core/src/types.ts +++ b/packages/amis-core/src/types.ts @@ -405,9 +405,38 @@ export interface PlainObject { [propsName: string]: any; } +export interface DataChangeReason { + type: + | 'input' // 用户输入 + | 'api' // api 接口返回触发 + | 'formula' // 公式计算触发 + | 'hide' // 隐藏属性变化触发 + | 'init' // 表单项初始化触发 + | 'action'; // 事件动作触发 + + // 变化的字段名 + // 如果是整体变化,那么是 undefined + name?: string; + + // 变化的值 + value?: any; +} + export interface RendererData { [propsName: string]: any; + /** + * 记录变化前的数据 + */ __prev?: RendererDataAlias; + + /** + * 记录变化的信息 + */ + __changeReason?: DataChangeReason; + + /** + * 记录上层数据 + */ __super?: RendererData; } type RendererDataAlias = RendererData; diff --git a/packages/amis-editor-core/src/plugin.ts b/packages/amis-editor-core/src/plugin.ts index 4bea29a08..af335b75a 100644 --- a/packages/amis-editor-core/src/plugin.ts +++ b/packages/amis-editor-core/src/plugin.ts @@ -18,7 +18,7 @@ import type {RendererConfig, Schema} from 'amis-core'; import type {MenuDivider, MenuItem} from 'amis-ui/lib/components/ContextMenu'; import type {BaseSchema, SchemaCollection} from 'amis'; import type {AsyncLayerOptions} from './component/AsyncLayer'; -import type {SchemaType} from 'packages/amis/src/Schema'; +import type {SchemaType} from 'amis/lib/Schema'; /** * 区域的定义,容器渲染器都需要定义区域信息。 diff --git a/packages/amis-editor-core/src/store/editor.ts b/packages/amis-editor-core/src/store/editor.ts index a044ae575..7b70ec6b4 100644 --- a/packages/amis-editor-core/src/store/editor.ts +++ b/packages/amis-editor-core/src/store/editor.ts @@ -25,7 +25,7 @@ import { addModal, mergeDefinitions, getModals -} from '../../src/util'; +} from '../util'; import { InsertEventContext, PluginEvent, @@ -60,8 +60,8 @@ import {EditorNode, EditorNodeType} from './node'; import findIndex from 'lodash/findIndex'; import {matchSorter} from 'match-sorter'; import debounce from 'lodash/debounce'; -import type {DialogSchema} from '../../../amis/src/renderers/Dialog'; -import type {DrawerSchema} from '../../../amis/src/renderers/Drawer'; +import type {DialogSchema} from 'amis/lib/renderers/Dialog'; +import type {DrawerSchema} from 'amis/lib/renderers/Drawer'; import getLayoutInstance from '../layout'; export interface SchemaHistory { diff --git a/packages/amis-editor-core/src/util.ts b/packages/amis-editor-core/src/util.ts index 22e4af8ff..f8c8f3f44 100644 --- a/packages/amis-editor-core/src/util.ts +++ b/packages/amis-editor-core/src/util.ts @@ -23,8 +23,8 @@ import merge from 'lodash/merge'; import {EditorModalBody} from './store/editor'; import {filter} from 'lodash'; import type {SchemaType} from 'amis/lib/Schema'; -import type {DialogSchema} from '../../amis/src/renderers/Dialog'; -import type {DrawerSchema} from '../../amis/src/renderers/Drawer'; +import type {DialogSchema} from 'amis/lib/renderers/Dialog'; +import type {DrawerSchema} from 'amis/lib/renderers/Drawer'; const { guid, diff --git a/packages/amis-editor/src/plugin/Dialog.tsx b/packages/amis-editor/src/plugin/Dialog.tsx index 213db6ce0..6ea63e26f 100644 --- a/packages/amis-editor/src/plugin/Dialog.tsx +++ b/packages/amis-editor/src/plugin/Dialog.tsx @@ -21,7 +21,7 @@ import { import {getEventControlConfig} from '../renderer/event-control/helper'; import omit from 'lodash/omit'; import type {RendererConfig, Schema} from 'amis-core'; -import {ModalProps} from 'amis-ui/src/components/Modal'; +import {ModalProps} from 'amis-ui/lib/components/Modal'; import ModalSettingPanel from '../component/ModalSettingPanel'; import find from 'lodash/find'; diff --git a/packages/amis-editor/src/renderer/FormulaControl.tsx b/packages/amis-editor/src/renderer/FormulaControl.tsx index 302da9e62..27914cba9 100644 --- a/packages/amis-editor/src/renderer/FormulaControl.tsx +++ b/packages/amis-editor/src/renderer/FormulaControl.tsx @@ -27,7 +27,7 @@ import {getVariables, getQuickVariables, utils} from 'amis-editor-core'; import type {BaseEventContext} from 'amis-editor-core'; import type {VariableItem, FuncGroup} from 'amis-ui'; -import {SchemaType} from 'packages/amis/src/Schema'; +import {SchemaType} from 'amis/lib/Schema'; export enum FormulaDateType { NotDate, // 不是时间类 diff --git a/packages/amis-editor/src/renderer/StatusControl.tsx b/packages/amis-editor/src/renderer/StatusControl.tsx index e5e765543..edfe8eea0 100644 --- a/packages/amis-editor/src/renderer/StatusControl.tsx +++ b/packages/amis-editor/src/renderer/StatusControl.tsx @@ -10,7 +10,7 @@ import {autobind, getSchemaTpl} from 'amis-editor-core'; import type {FormControlProps} from 'amis-core'; import type {SchemaCollection} from 'amis'; -import type {FormSchema} from '../../../amis/src/Schema'; +import type {FormSchema} from 'amis/lib/Schema'; export interface StatusControlProps extends FormControlProps { name: string; diff --git a/packages/amis-editor/src/renderer/event-control/DialogActionPanel.tsx b/packages/amis-editor/src/renderer/event-control/DialogActionPanel.tsx index 19d300e0f..b857f3cc7 100644 --- a/packages/amis-editor/src/renderer/event-control/DialogActionPanel.tsx +++ b/packages/amis-editor/src/renderer/event-control/DialogActionPanel.tsx @@ -23,7 +23,7 @@ import { Select, Switch } from 'amis-ui'; -import type {EditorModalBody} from '../../../../amis-editor-core/src/store/editor'; +import type {EditorModalBody} from 'amis-editor-core/lib/store/editor'; export interface DialogActionPanelProps extends RendererProps { manager: EditorManager; diff --git a/packages/amis-editor/src/renderer/event-control/index.tsx b/packages/amis-editor/src/renderer/event-control/index.tsx index bda247607..95002b2f7 100644 --- a/packages/amis-editor/src/renderer/event-control/index.tsx +++ b/packages/amis-editor/src/renderer/event-control/index.tsx @@ -47,7 +47,7 @@ import { } from 'amis-editor-core'; export * from './helper'; import {i18n as _i18n} from 'i18n-runtime'; -import type {VariableItem} from 'amis-ui/src/components/formula/CodeEditor'; +import type {VariableItem} from 'amis-ui/lib/components/formula/CodeEditor'; import {reaction} from 'mobx'; import {updateComponentContext} from 'amis-editor-core'; diff --git a/packages/amis-editor/src/tpl/common.tsx b/packages/amis-editor/src/tpl/common.tsx index b5b257db9..3af88f4cd 100644 --- a/packages/amis-editor/src/tpl/common.tsx +++ b/packages/amis-editor/src/tpl/common.tsx @@ -10,7 +10,7 @@ import type {SchemaObject} from 'amis'; import flatten from 'lodash/flatten'; import {InputComponentName} from '../component/InputComponentName'; import {FormulaDateType} from '../renderer/FormulaControl'; -import type {VariableItem} from 'amis-ui/src/components/formula/CodeEditor'; +import type {VariableItem} from 'amis-ui/lib/components/formula/CodeEditor'; import reduce from 'lodash/reduce'; import map from 'lodash/map'; import omit from 'lodash/omit'; diff --git a/packages/amis/__tests__/renderers/CRUDfilter.test.tsx b/packages/amis/__tests__/renderers/CRUDfilter.test.tsx index 5c33b513f..63bb2a714 100644 --- a/packages/amis/__tests__/renderers/CRUDfilter.test.tsx +++ b/packages/amis/__tests__/renderers/CRUDfilter.test.tsx @@ -307,7 +307,7 @@ test('Picker filter2', async () => { fireEvent.click(pickerBtn); - await wait(500); + await wait(1000); const a = container.querySelector('input[name="a"]')!; const b = container.querySelector('input[name="b"]')!; diff --git a/packages/amis/src/renderers/Service.tsx b/packages/amis/src/renderers/Service.tsx index c181eee29..5f000d983 100644 --- a/packages/amis/src/renderers/Service.tsx +++ b/packages/amis/src/renderers/Service.tsx @@ -543,7 +543,9 @@ export default class Service extends React.Component { ); if (!isEmpty(data) && onBulkChange && formStore) { - onBulkChange(data); + onBulkChange(data, false, { + type: 'api' + }); } result?.ok && this.initInterval(data); diff --git a/packages/amis/src/types.ts b/packages/amis/src/types.ts index 3b8b0718f..1e4e62afe 100644 --- a/packages/amis/src/types.ts +++ b/packages/amis/src/types.ts @@ -1,3 +1,4 @@ +import {DataChangeReason} from 'amis-core'; import type {ActionSchema} from './renderers/Action'; import {SchemaApi, SchemaApiObject} from './Schema'; @@ -156,7 +157,20 @@ export interface PlainObject { export interface RendererData { [propsName: string]: any; + + /** + * 记录变化前的数据 + */ __prev?: RendererDataAlias; + + /** + * 记录变化的信息 + */ + __changeReason?: DataChangeReason; + + /** + * 记录上层数据 + */ __super?: RendererData; } type RendererDataAlias = RendererData;