feat(form): onChange添加setModel参数,用于修改model并添加至修改记录中

This commit is contained in:
roymondchen 2025-04-21 19:42:22 +08:00
parent 31515c4046
commit 5e0e776d40
14 changed files with 70 additions and 47 deletions

View File

@ -80,13 +80,11 @@ const codeConfig = computed<GroupListConfig>(() => ({
{ value: HookCodeType.DATA_SOURCE_METHOD, text: '数据源方法' }, { value: HookCodeType.DATA_SOURCE_METHOD, text: '数据源方法' },
], ],
defaultValue: 'code', defaultValue: 'code',
onChange: (mForm, v: HookCodeType, { model, prop, changeRecords }) => { onChange: (_mForm, v: HookCodeType, { setModel }) => {
if (v === HookCodeType.DATA_SOURCE_METHOD) { if (v === HookCodeType.DATA_SOURCE_METHOD) {
model.codeId = []; setModel('codeId', []);
changeRecords.push({ propPath: prop.replace('codeType', 'codeId'), value: [] });
} else { } else {
model.codeId = ''; setModel('codeId', '');
changeRecords.push({ propPath: prop.replace('codeType', 'codeId'), value: '' });
} }
return v; return v;
@ -97,7 +95,7 @@ const codeConfig = computed<GroupListConfig>(() => ({
name: 'codeId', name: 'codeId',
span: 18, span: 18,
labelWidth: 0, labelWidth: 0,
display: (mForm, { model }) => model.codeType !== HookCodeType.DATA_SOURCE_METHOD, display: (_mForm, { model }) => model.codeType !== HookCodeType.DATA_SOURCE_METHOD,
notEditable: () => !codeBlockService.getEditStatus(), notEditable: () => !codeBlockService.getEditStatus(),
}, },
{ {
@ -105,7 +103,7 @@ const codeConfig = computed<GroupListConfig>(() => ({
name: 'codeId', name: 'codeId',
span: 18, span: 18,
labelWidth: 0, labelWidth: 0,
display: (mForm, { model }) => model.codeType === HookCodeType.DATA_SOURCE_METHOD, display: (_mForm, { model }) => model.codeType === HookCodeType.DATA_SOURCE_METHOD,
notEditable: () => !dataSourceService.get('editable'), notEditable: () => !dataSourceService.get('editable'),
}, },
], ],

View File

@ -121,24 +121,28 @@ const selectConfig = {
} }
return []; return [];
}, },
onChange: (formState: any, codeId: Id, { model }: any) => { onChange: (formState: any, codeId: Id, { setModel, model }: any) => {
// codeIdmodelcodeIdparams // codeIdmodelcodeIdparams
paramsConfig.value = getParamItemsConfig(codeId); paramsConfig.value = getParamItemsConfig(codeId);
if (paramsConfig.value.length) { if (paramsConfig.value.length) {
model.params = createValues(formState, paramsConfig.value, {}, model.params); setModel('params', createValues(formState, paramsConfig.value, {}, model.params));
} else { } else {
model.params = {}; setModel('params', {});
} }
return codeId; return codeId;
}, },
}; };
const onCodeIdChangeHandler = (value: any) => { const onCodeIdChangeHandler = (value: any, eventData: ContainerChangeEventData) => {
props.model.params = value.params; props.model.params = value.params;
emit('change', props.model, { emit('change', props.model, {
changeRecords: [ changeRecords: eventData.changeRecords?.map((item) => ({
prop: `${props.prop.replace(props.name, '')}${item.propPath}`,
value: item.value,
})) || [
{ {
propPath: props.prop, propPath: props.prop,
value: value[props.name], value: value[props.name],

View File

@ -65,6 +65,7 @@ import FloatingBox from '@editor/components/FloatingBox.vue';
import { useEditorContentHeight } from '@editor/hooks'; import { useEditorContentHeight } from '@editor/hooks';
import { useNextFloatBoxPosition } from '@editor/hooks/use-next-float-box-position'; import { useNextFloatBoxPosition } from '@editor/hooks/use-next-float-box-position';
import { useServices } from '@editor/hooks/use-services'; import { useServices } from '@editor/hooks/use-services';
import { error } from '@editor/utils/logger';
defineOptions({ defineOptions({
name: 'MFieldsDataSourceFields', name: 'MFieldsDataSourceFields',
@ -144,6 +145,7 @@ const fieldColumns: ColumnConfig[] = [
try { try {
return JSON.stringify(row.defaultValue); return JSON.stringify(row.defaultValue);
} catch (e) { } catch (e) {
error(e);
return row.defaultValue; return row.defaultValue;
} }
}, },
@ -193,9 +195,9 @@ const dataSourceFieldsConfig: FormConfig = [
{ text: 'null', value: 'null' }, { text: 'null', value: 'null' },
{ text: 'any', value: 'any' }, { text: 'any', value: 'any' },
], ],
onChange: (formState, v: string, { model }) => { onChange: (_formState, v: string, { setModel }) => {
if (!['any', 'array', 'object'].includes(v)) { if (!['any', 'array', 'object'].includes(v)) {
model.fields = []; setModel('fields', []);
} }
return v; return v;
}, },

View File

@ -37,7 +37,14 @@ import { Edit, View } from '@element-plus/icons-vue';
import type { Id } from '@tmagic/core'; import type { Id } from '@tmagic/core';
import { TMagicButton, TMagicTooltip } from '@tmagic/design'; import { TMagicButton, TMagicTooltip } from '@tmagic/design';
import { createValues, type FieldProps, filterFunction, type FormState, MContainer } from '@tmagic/form'; import {
createValues,
type FieldProps,
filterFunction,
type FormState,
MContainer,
type OnChangeHandlerData,
} from '@tmagic/form';
import CodeParams from '@editor/components/CodeParams.vue'; import CodeParams from '@editor/components/CodeParams.vue';
import MIcon from '@editor/components/Icon.vue'; import MIcon from '@editor/components/Icon.vue';
@ -92,14 +99,18 @@ const getParamItemsConfig = ([dataSourceId, methodName]: [Id, string] = ['', '']
const paramsConfig = ref<CodeParamStatement[]>(getParamItemsConfig(props.model[props.name || 'dataSourceMethod'])); const paramsConfig = ref<CodeParamStatement[]>(getParamItemsConfig(props.model[props.name || 'dataSourceMethod']));
const setParamsConfig = (dataSourceMethod: [Id, string], formState: any = {}) => { const setParamsConfig = (
dataSourceMethod: [Id, string],
formState: any = {},
setModel: OnChangeHandlerData['setModel'],
) => {
// codeIdmodelcodeIdparams // codeIdmodelcodeIdparams
paramsConfig.value = dataSourceMethod ? getParamItemsConfig(dataSourceMethod) : []; paramsConfig.value = dataSourceMethod ? getParamItemsConfig(dataSourceMethod) : [];
if (paramsConfig.value.length) { if (paramsConfig.value.length) {
props.model.params = createValues(formState, paramsConfig.value, {}, props.model.params); setModel('params', createValues(formState, paramsConfig.value, {}, props.model.params));
} else { } else {
props.model.params = {}; setModel('params', {});
} }
}; };
@ -125,8 +136,8 @@ const cascaderConfig = computed(() => ({
name: props.name, name: props.name,
options: methodsOptions.value, options: methodsOptions.value,
disable: props.disabled, disable: props.disabled,
onChange: (formState: any, dataSourceMethod: [Id, string]) => { onChange: (formState: any, dataSourceMethod: [Id, string], { setModel }: OnChangeHandlerData) => {
setParamsConfig(dataSourceMethod, formState); setParamsConfig(dataSourceMethod, formState, setModel);
return dataSourceMethod; return dataSourceMethod;
}, },

View File

@ -63,6 +63,7 @@ import type {
ContainerChangeEventData, ContainerChangeEventData,
FieldProps, FieldProps,
FormState, FormState,
OnChangeHandlerData,
PanelConfig, PanelConfig,
} from '@tmagic/form'; } from '@tmagic/form';
import { MContainer as MFormContainer, MPanel } from '@tmagic/form'; import { MContainer as MFormContainer, MPanel } from '@tmagic/form';
@ -202,8 +203,8 @@ const targetCompConfig = computed(() => {
text: '联动组件', text: '联动组件',
type: 'ui-select', type: 'ui-select',
display: (mForm: FormState, { model }: { model: Record<any, any> }) => model.actionType === ActionType.COMP, display: (mForm: FormState, { model }: { model: Record<any, any> }) => model.actionType === ActionType.COMP,
onChange: (MForm: FormState, v: string, { model }: any) => { onChange: (MForm: FormState, v: string, { setModel }: OnChangeHandlerData) => {
model.method = ''; setModel('method', '');
return v; return v;
}, },
}; };

View File

@ -228,6 +228,7 @@ import { WarningFilled } from '@element-plus/icons-vue';
import { isEqual } from 'lodash-es'; import { isEqual } from 'lodash-es';
import { TMagicButton, TMagicFormItem, TMagicIcon, TMagicTooltip } from '@tmagic/design'; import { TMagicButton, TMagicFormItem, TMagicIcon, TMagicTooltip } from '@tmagic/design';
import { setValueByKeyPath } from '@tmagic/utils';
import type { ChildConfig, ContainerChangeEventData, ContainerCommonConfig, FormState, FormValue } from '../schema'; import type { ChildConfig, ContainerChangeEventData, ContainerCommonConfig, FormState, FormValue } from '../schema';
import { display as displayFunction, filterFunction, getRules } from '../utils/form'; import { display as displayFunction, filterFunction, getRules } from '../utils/form';
@ -423,6 +424,12 @@ const onChangeHandler = async function (v: any, eventData: ContainerChangeEventD
prop: itemProp.value, prop: itemProp.value,
config: props.config, config: props.config,
changeRecords: newChangeRecords, changeRecords: newChangeRecords,
setModel: (key: string, value: any) => {
setValueByKeyPath(key, value, props.model);
if (props.config.name) {
newChangeRecords.push({ propPath: itemProp.value.replace(`${props.config.name}`, key), value });
}
},
})) ?? value; })) ?? value;
} }
value = trimHandler(trim, value) ?? value; value = trimHandler(trim, value) ?? value;
@ -442,10 +449,10 @@ const onChangeHandler = async function (v: any, eventData: ContainerChangeEventD
valueProp = valueProp ? `${valueProp}.${eventData.modifyKey}` : eventData.modifyKey!; valueProp = valueProp ? `${valueProp}.${eventData.modifyKey}` : eventData.modifyKey!;
// modifyKey // modifyKey
// eslint-disable-next-line no-param-reassign
delete eventData.modifyKey; delete eventData.modifyKey;
} else if (isValidName() && props.model !== value && (v !== value || props.model[name.value] !== value)) { } else if (isValidName() && props.model !== value && (v !== value || props.model[name.value] !== value)) {
// fieldfield-linkmodel===value, // fieldfield-linkmodel===value,
// eslint-disable-next-line vue/no-mutating-props
props.model[name.value] = value; props.model[name.value] = value;
} }

View File

@ -28,14 +28,14 @@ export default [
{ value: 'absolute', text: '绝对定位' }, { value: 'absolute', text: '绝对定位' },
{ value: 'relative', text: '流式布局' }, { value: 'relative', text: '流式布局' },
], ],
onChange: (formState: any, v: string, { model }: any) => { onChange: (formState: any, v: string, { setModel, model }: any) => {
if (!model.style) return v; if (!model.style) return v;
if (v === 'relative') { if (v === 'relative') {
model.style.height = 'auto'; setModel('style.height', 'auto');
} else { } else {
const el = getElById()(formState.stage?.renderer?.contentWindow.document, model.id); const el = getElById()(formState.stage?.renderer?.contentWindow.document, model.id);
if (el) { if (el) {
model.style.height = el.getBoundingClientRect().height; setModel('style.height', el.getBoundingClientRect().height);
} }
} }
}, },

View File

@ -25,12 +25,12 @@ export default [
dataSourceFieldType: ['array'], dataSourceFieldType: ['array'],
checkStrictly: true, checkStrictly: true,
type: 'data-source-field-select', type: 'data-source-field-select',
onChange: (_vm: any, v: string[] = [], { model }: any) => { onChange: (_vm: any, v: string[] = [], { setModel }: any) => {
if (Array.isArray(v) && v.length > 1) { if (Array.isArray(v) && v.length > 1) {
const [dsId, ...keys] = v; const [dsId, ...keys] = v;
model.dsField = [dsId.replace(DATA_SOURCE_FIELDS_SELECT_VALUE_PREFIX, ''), ...keys]; setModel('dsField', [dsId.replace(DATA_SOURCE_FIELDS_SELECT_VALUE_PREFIX, ''), ...keys]);
} else { } else {
model.dsField = []; setModel('dsField', []);
} }
}, },
}, },

View File

@ -37,14 +37,14 @@ export default [
{ value: 'absolute', text: '绝对定位' }, { value: 'absolute', text: '绝对定位' },
{ value: 'relative', text: '流式布局' }, { value: 'relative', text: '流式布局' },
], ],
onChange: (formState: any, v: string, { model }: any) => { onChange: (formState: any, v: string, { model, setModel }: any) => {
if (!model.style) return v; if (!model.style) return v;
if (v === 'relative') { if (v === 'relative') {
model.style.height = 'auto'; setModel('style.height', 'auto');
} else { } else {
const el = getElById()(formState.stage?.renderer?.contentWindow.document, model.id); const el = getElById()(formState.stage?.renderer?.contentWindow.document, model.id);
if (el) { if (el) {
model.style.height = el.getBoundingClientRect().height; setModel('style.height', el.getBoundingClientRect().height);
} }
} }
}, },

View File

@ -39,14 +39,14 @@ export default [
{ value: 'absolute', text: '绝对定位' }, { value: 'absolute', text: '绝对定位' },
{ value: 'relative', text: '流式布局' }, { value: 'relative', text: '流式布局' },
], ],
onChange: (formState: any, v: string, { model }: any) => { onChange: (formState: any, v: string, { model, setModel }: any) => {
if (!model.style) return v; if (!model.style) return v;
if (v === 'relative') { if (v === 'relative') {
model.style.height = 'auto'; setModel('style.height', 'auto');
} else { } else {
const el = getElById()(formState.stage?.renderer?.contentWindow.document, model.id); const el = getElById()(formState.stage?.renderer?.contentWindow.document, model.id);
if (el) { if (el) {
model.style.height = el.getBoundingClientRect().height; setModel('style.height', el.getBoundingClientRect().height);
} }
} }
}, },

View File

@ -33,14 +33,14 @@ export default [
{ value: 'absolute', text: '绝对定位' }, { value: 'absolute', text: '绝对定位' },
{ value: 'relative', text: '流式布局' }, { value: 'relative', text: '流式布局' },
], ],
onChange: (formState: any, v: string, { model }: any) => { onChange: (formState: any, v: string, { model, setModel }: any) => {
if (!model.style) return v; if (!model.style) return v;
if (v === 'relative') { if (v === 'relative') {
model.style.height = 'auto'; setModel('style.height', 'auto');
} else { } else {
const el = getElById()(formState.stage?.renderer?.contentWindow.document, model.id); const el = getElById()(formState.stage?.renderer?.contentWindow.document, model.id);
if (el) { if (el) {
model.style.height = el.getBoundingClientRect().height; setModel('style.height', el.getBoundingClientRect().height);
} }
} }
}, },

View File

@ -30,12 +30,12 @@ export default [
dataSourceFieldType: ['array'], dataSourceFieldType: ['array'],
checkStrictly: true, checkStrictly: true,
type: 'data-source-field-select', type: 'data-source-field-select',
onChange: (_vm: any, v: string[] = [], { model }: any) => { onChange: (_vm: any, v: string[] = [], { setModel }: any) => {
if (Array.isArray(v) && v.length > 1) { if (Array.isArray(v) && v.length > 1) {
const [dsId, ...keys] = v; const [dsId, ...keys] = v;
model.dsField = [dsId.replace(DATA_SOURCE_FIELDS_SELECT_VALUE_PREFIX, ''), ...keys]; setModel('dsField', [dsId.replace(DATA_SOURCE_FIELDS_SELECT_VALUE_PREFIX, ''), ...keys]);
} else { } else {
model.dsField = []; setModel('dsField', []);
} }
}, },
}, },

View File

@ -37,14 +37,14 @@ export default [
{ value: 'absolute', text: '绝对定位' }, { value: 'absolute', text: '绝对定位' },
{ value: 'relative', text: '流式布局' }, { value: 'relative', text: '流式布局' },
], ],
onChange: (formState: any, v: string, { model }: any) => { onChange: (formState: any, v: string, { model, setModel }: any) => {
if (!model.style) return v; if (!model.style) return v;
if (v === 'relative') { if (v === 'relative') {
model.style.height = 'auto'; setModel('style.height', 'auto');
} else { } else {
const el = getElById()(formState.stage?.renderer?.contentWindow.document, model.id); const el = getElById()(formState.stage?.renderer?.contentWindow.document, model.id);
if (el) { if (el) {
model.style.height = el.getBoundingClientRect().height; setModel('style.height', el.getBoundingClientRect().height);
} }
} }
}, },

View File

@ -38,14 +38,14 @@ export default [
{ value: 'absolute', text: '绝对定位' }, { value: 'absolute', text: '绝对定位' },
{ value: 'relative', text: '流式布局' }, { value: 'relative', text: '流式布局' },
], ],
onChange: (formState: any, v: string, { model }: any) => { onChange: (formState: any, v: string, { model, setModel }: any) => {
if (!model.style) return v; if (!model.style) return v;
if (v === 'relative') { if (v === 'relative') {
model.style.height = 'auto'; setModel('style.height', 'auto');
} else { } else {
const el = getElById()(formState.stage?.renderer?.contentWindow.document, model.id); const el = getElById()(formState.stage?.renderer?.contentWindow.document, model.id);
if (el) { if (el) {
model.style.height = el.getBoundingClientRect().height; setModel('style.height', el.getBoundingClientRect().height);
} }
} }
}, },