Skip to content

Commit

Permalink
feat(editor): 组件代码块的绑定关系记录到dsl中,修复删除组件解除关系的问题,代码块dsl支持扩展字段
Browse files Browse the repository at this point in the history
  • Loading branch information
parisma authored and jia000 committed Sep 22, 2022
1 parent 0b3585c commit 92f3696
Show file tree
Hide file tree
Showing 7 changed files with 201 additions and 154 deletions.
35 changes: 0 additions & 35 deletions packages/editor/src/Editor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@

<script lang="ts">
import { defineComponent, onUnmounted, PropType, provide, reactive, toRaw, watch } from 'vue';
import { isEmpty,union } from 'lodash-es';
import { EventOption } from '@tmagic/core';
import type { FormConfig } from '@tmagic/form';
Expand Down Expand Up @@ -210,12 +209,6 @@ export default defineComponent({
updateDragEl: {
type: Function as PropType<(el: HTMLDivElement, target: HTMLElement) => void>,
},
/** 可挂载代码块的生命周期 */
codeHooks: {
type: Array<string>,
default: () => ['created', 'mounted'],
},
},
emits: ['props-panel-mounted', 'update:modelValue'],
Expand All @@ -233,38 +226,11 @@ export default defineComponent({
emit('update:modelValue', toRaw(editorService.get('root')));
});
const initCodeRelation = (rootValue: MNode) => {
if (isEmpty(rootValue.items)) return;
rootValue.items.forEach((nodeValue: MNode) => {
let curNodeCombineIds:string[] = []
// 合并各钩子绑定的代码块Id
props.codeHooks.forEach((hook) => {
// continue
if (isEmpty(nodeValue[hook])) return true
// 兼容单选绑定场景
if(typeof nodeValue[hook] === 'string' && nodeValue[hook]) {
curNodeCombineIds = union(curNodeCombineIds,[nodeValue[hook]])
}else if(Array.isArray(nodeValue[hook])) {
curNodeCombineIds = union(curNodeCombineIds,nodeValue[hook])
}
});
// 设置组件与代码块的绑定关系
if(!isEmpty(curNodeCombineIds)) {
codeBlockService.setCompRelation(nodeValue.id, curNodeCombineIds);
}
if (!isEmpty(nodeValue.items)) {
initCodeRelation(nodeValue);
}
});
};
// 初始值变化,重新设置节点信息
watch(
() => props.modelValue,
(modelValue) => {
editorService.set('root', modelValue);
// 初始化代码块与组件的绑定关系
initCodeRelation(modelValue);
},
{
immediate: true,
Expand Down Expand Up @@ -370,7 +336,6 @@ export default defineComponent({
containerHighlightType: props.containerHighlightType,
}),
);
provide('codeHooks',props.codeHooks)
return services;
},
Expand Down
54 changes: 33 additions & 21 deletions packages/editor/src/fields/CodeSelect.vue
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,13 @@
<script lang="ts" setup>
import { computed, defineEmits, defineProps, inject, ref, watchEffect } from 'vue';
import { ElMessage } from 'element-plus';
import { map, union } from 'lodash-es';
import { cloneDeep, map, xor } from 'lodash-es';
import { SelectConfig } from '@tmagic/form';
import type { Services } from '../type';
import { CodeEditorMode } from '../type';
import { CodeEditorMode, CodeSelectOp } from '../type';
const services = inject<Services>('services');
const codeHooks = inject<string[]>('codeHooks');
const emit = defineEmits(['change']);
Expand Down Expand Up @@ -77,7 +76,9 @@ const selectConfig = computed(() => {
};
});
const fieldKey = ref('');
const multiple = ref(true);
const combineIds = ref<string[]>([]);
let lastTagSnapshot = cloneDeep(props.model[props.name]) || [];
watchEffect(async () => {
const combineNames = await Promise.all(
Expand All @@ -90,37 +91,48 @@ watchEffect(async () => {
});
const changeHandler = async (value: any) => {
await setCombineRelation();
let codeIds = value;
if (typeof value === 'string') {
multiple.value = false;
lastTagSnapshot = [lastTagSnapshot];
codeIds = value ? [value] : [];
}
await setCombineRelation(codeIds);
emit('change', value);
};
// 同步绑定关系
const setCombineRelation = async () => {
// 绑定数组先置空
combineIds.value = [];
const setCombineRelation = async (codeIds: string[]) => {
// 组件id
const { id = '' } = services?.editorService.get('node') || {};
codeHooks?.forEach((hook) => {
// continue
if (!props.model[hook]) return true;
if (typeof props.model[hook] === 'string' && props.model[hook]) {
combineIds.value = union(combineIds.value, [props.model[hook]]);
} else if (Array.isArray(props.model[hook])) {
combineIds.value = union(combineIds.value, props.model[hook]);
}
});
// 记录组件与代码块的绑定关系
await services?.codeBlockService.setCompRelation(id, combineIds.value);
// 记录当前已被绑定的代码块,为查看弹窗的展示内容
await services?.codeBlockService.setCombineIds(combineIds.value);
// 兼容单选
let opFlag = CodeSelectOp.CHANGE;
let diffValues = codeIds;
if (multiple.value) {
opFlag = codeIds.length < lastTagSnapshot.length ? CodeSelectOp.DELETE : CodeSelectOp.ADD;
diffValues = xor(codeIds, lastTagSnapshot) as string[];
}
// 记录绑定关系
await services?.codeBlockService.setCombineRelation(id, diffValues, opFlag, props.prop);
lastTagSnapshot = codeIds;
await setCombineIds(codeIds);
};
// 记录当前已被绑定的代码块,为查看弹窗的展示内容
const setCombineIds = async (codeIds: string[]) => {
combineIds.value = codeIds;
await services?.codeBlockService.setCombineIds(codeIds);
};
const viewHandler = async () => {
if (props.model[props.name].length === 0) {
ElMessage.error('请先绑定代码块');
return;
}
await setCombineRelation();
// 记录当前已被绑定的代码块,为查看弹窗的展示内容
await setCombineIds(props.model[props.name]);
await services?.codeBlockService.setMode(CodeEditorMode.LIST);
services?.codeBlockService.setCodeEditorContent(true, combineIds.value[0]);
};
Expand Down
45 changes: 15 additions & 30 deletions packages/editor/src/layouts/sidebar/code-block/CodeBlockList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -97,14 +97,14 @@
import { computed, inject, reactive, ref, watch } from 'vue';
import { Close, Edit, Link, View } from '@element-plus/icons-vue';
import { ElMessage } from 'element-plus';
import { flattenDeep, forIn, isEmpty, values, xor } from 'lodash-es';
import { forIn, isEmpty } from 'lodash-es';
import { Id } from '@tmagic/schema';
import StageCore from '@tmagic/stage';
import Icon from '../../../components/Icon.vue';
import type { CodeBlockContent, Services } from '../../../type';
import { CodeDeleteErrorType, CodeDslList, CodeEditorMode, ListState } from '../../../type';
import type { CodeBlockContent, CodeRelation, Services } from '../../../type';
import { CodeDeleteErrorType, CodeDslList, CodeEditorMode, ListRelationState } from '../../../type';
import codeBlockEditor from './CodeBlockEditor.vue';
Expand All @@ -113,24 +113,25 @@ const props = defineProps<{
}>();
const services = inject<Services>('services');
// const codeHooks = inject<string[]>('codeHooks') || [];
// 代码块列表
const state = reactive<ListState>({
const state = reactive<ListRelationState>({
codeList: [],
bindComps: {},
});
const editable = computed(() => services?.codeBlockService.getEditStatus());
// 根据代码块ID获取其绑定的组件信息
const getBindCompsByCodeId = (codeId: string) => {
const bindCompIds = services?.codeBlockService.getCodeRelationById(codeId) || [];
if (isEmpty(bindCompIds)) {
const getBindCompsByCodeId = (codeId: string, codeBlockContent: CodeBlockContent) => {
if (isEmpty(codeBlockContent) || isEmpty(codeBlockContent.comps)) {
state.bindComps[codeId] = [];
return;
}
const compsInfo = bindCompIds.map((compId) => ({
const compsField = codeBlockContent.comps as CodeRelation;
const bindCompIds = Object.keys(compsField);
const bindCompsFiltered = bindCompIds.filter((compId) => !isEmpty(compsField[compId]));
const compsInfo = bindCompsFiltered.map((compId) => ({
id: compId,
name: getCompName(compId),
}));
Expand All @@ -143,7 +144,7 @@ const initList = async () => {
if (!codeDsl) return;
state.codeList = [];
forIn(codeDsl, (value: CodeBlockContent, codeId: string) => {
getBindCompsByCodeId(codeId);
getBindCompsByCodeId(codeId, value);
state.codeList.push({
id: codeId,
name: value.name,
Expand All @@ -160,22 +161,7 @@ watch(
},
{
immediate: true,
},
);
// 监听绑定关系修改,更新到代码块列表
watch(
() => services?.codeBlockService.getCompRelation(),
(curRelation, oldRelation) => {
forIn(curRelation, (codeArr, compId) => {
let oldCodeArr: string[] = [];
if (oldRelation) {
oldCodeArr = oldRelation[compId];
}
// 可能一次清空全部绑定关系,对比结果为数组
const diffCodeIds = xor(codeArr, oldCodeArr);
diffCodeIds.forEach((codeId) => getBindCompsByCodeId(codeId));
});
deep: true,
},
);
Expand Down Expand Up @@ -219,15 +205,14 @@ const editCode = async (key: string) => {
// 删除代码块
const deleteCode = (key: string) => {
const compRelation = services?.codeBlockService.getCompRelation();
const codeIds = flattenDeep(values(compRelation));
const existBinds = !!(state.bindComps[key]?.length > 0);
const undeleteableList = services?.codeBlockService.getUndeletableList() || [];
if (!codeIds.includes(key) && !undeleteableList.includes(key)) {
if (!existBinds && !undeleteableList.includes(key)) {
// 无绑定关系,且不在不可删除列表中
services?.codeBlockService.deleteCodeDslByIds([key]);
} else {
if (typeof props.customError === 'function') {
props.customError(key, codeIds.includes(key) ? CodeDeleteErrorType.BIND : CodeDeleteErrorType.UNDELETEABLE);
props.customError(key, existBinds ? CodeDeleteErrorType.BIND : CodeDeleteErrorType.UNDELETEABLE);
} else {
ElMessage.error('代码块删除失败');
}
Expand Down
Loading

0 comments on commit 92f3696

Please sign in to comment.