mirror of
https://gitee.com/baidu/amis.git
synced 2024-11-29 18:48:45 +08:00
Merge pull request #9248 from wibetter/fix-widget-tpl
fix(amis-editor): addChild新增reGenerateId参数控制,并优化reGenerateID逻辑
This commit is contained in:
commit
d2f5fc20bf
@ -535,9 +535,9 @@ export default class Editor extends Component<EditorProps> {
|
||||
);
|
||||
if (this.store.activeId === this.curCopySchemaData.$$id) {
|
||||
// 复制和粘贴是同一个元素,则直接追加到当前元素后面
|
||||
this.manager.appendSiblingSchema(reGenerateID(curSimpleSchema));
|
||||
this.manager.appendSiblingSchema(reGenerateID(curSimpleSchema), false);
|
||||
} else {
|
||||
this.manager.addElem(reGenerateID(curSimpleSchema));
|
||||
this.manager.addElem(reGenerateID(curSimpleSchema), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -873,7 +873,7 @@ export class EditorManager {
|
||||
* @param rendererIdOrSchema
|
||||
* 备注:可以根据渲染器ID添加新元素,也可以根据现有schema片段添加新元素
|
||||
*/
|
||||
async addElem(rendererIdOrSchema: string | any) {
|
||||
async addElem(rendererIdOrSchema: string | any, reGenerateId?: boolean) {
|
||||
if (!rendererIdOrSchema) {
|
||||
return;
|
||||
}
|
||||
@ -923,7 +923,13 @@ export class EditorManager {
|
||||
!isSpecialLayout
|
||||
) {
|
||||
// 布局能力提升: 点击插入新元素,当wrapper为空插入布局容器时,自动改为置换,避免过多层级
|
||||
this.replaceChild(curActiveId, curElemSchema);
|
||||
this.replaceChild(
|
||||
curActiveId,
|
||||
curElemSchema,
|
||||
subRenderer,
|
||||
store.insertRegion,
|
||||
reGenerateId
|
||||
);
|
||||
setTimeout(() => {
|
||||
this.updateConfigPanel();
|
||||
}, 0);
|
||||
@ -1009,7 +1015,13 @@ export class EditorManager {
|
||||
regionNodeRegion,
|
||||
value,
|
||||
nextId,
|
||||
subRenderer
|
||||
subRenderer || node.info,
|
||||
{
|
||||
id: store.dragId,
|
||||
type: store.dragType,
|
||||
data: store.dragSchema
|
||||
},
|
||||
reGenerateId
|
||||
);
|
||||
if (child) {
|
||||
// mobx 修改数据是异步的
|
||||
@ -1049,7 +1061,8 @@ export class EditorManager {
|
||||
async appendSiblingSchema(
|
||||
rendererSchema: Object,
|
||||
beforeInsert?: boolean,
|
||||
disabledAutoSelectInsertElem?: boolean
|
||||
disabledAutoSelectInsertElem?: boolean,
|
||||
reGenerateId?: boolean
|
||||
) {
|
||||
if (!rendererSchema) {
|
||||
return;
|
||||
@ -1107,7 +1120,14 @@ export class EditorManager {
|
||||
regionNodeId,
|
||||
regionNodeRegion,
|
||||
rendererSchema,
|
||||
nextId
|
||||
nextId,
|
||||
node.info,
|
||||
{
|
||||
id: store.dragId,
|
||||
type: store.dragType,
|
||||
data: store.dragSchema
|
||||
},
|
||||
reGenerateId
|
||||
);
|
||||
if (child && !disabledAutoSelectInsertElem) {
|
||||
// mobx 修改数据是异步的
|
||||
@ -1536,19 +1556,20 @@ export class EditorManager {
|
||||
region: string,
|
||||
json: any,
|
||||
beforeId?: string,
|
||||
subRenderer?: SubRendererInfo,
|
||||
subRenderer?: SubRendererInfo | RendererInfo,
|
||||
dragInfo?: {
|
||||
id: string;
|
||||
type: string;
|
||||
data: any;
|
||||
}
|
||||
},
|
||||
reGenerateId?: boolean
|
||||
): any | null {
|
||||
const store = this.store;
|
||||
let index: number = -1;
|
||||
const commonContext = this.buildEventContext(id);
|
||||
|
||||
// 填充id,有些脚手架生成了复杂的布局等,自动填充一下id
|
||||
let curChildJson = JSONPipeIn(json, true);
|
||||
let curChildJson = JSONPipeIn(json, reGenerateId ?? true);
|
||||
|
||||
if (beforeId) {
|
||||
const arr = commonContext.schema[region];
|
||||
@ -1618,11 +1639,12 @@ export class EditorManager {
|
||||
replaceChild(
|
||||
id: string,
|
||||
json: any,
|
||||
subRenderer?: SubRendererInfo,
|
||||
region?: string
|
||||
subRenderer?: SubRendererInfo | RendererInfo,
|
||||
region?: string,
|
||||
reGenerateId?: boolean
|
||||
): boolean {
|
||||
// 转成普通json并添加node id
|
||||
let curJson = JSONPipeIn(json, true);
|
||||
let curJson = JSONPipeIn(json, reGenerateId ?? true);
|
||||
|
||||
const context: ReplaceEventContext = {
|
||||
...this.buildEventContext(id),
|
||||
|
@ -529,7 +529,7 @@ export interface InsertEventContext extends BaseEventContext {
|
||||
beforeId?: string;
|
||||
index: number;
|
||||
data: any;
|
||||
subRenderer?: SubRendererInfo;
|
||||
subRenderer?: SubRendererInfo | RendererInfo;
|
||||
dragInfo?: {
|
||||
id: string;
|
||||
type: string;
|
||||
@ -539,7 +539,7 @@ export interface InsertEventContext extends BaseEventContext {
|
||||
|
||||
export interface ReplaceEventContext extends BaseEventContext {
|
||||
data: any;
|
||||
subRenderer?: SubRendererInfo;
|
||||
subRenderer?: SubRendererInfo | RendererInfo;
|
||||
region?: string;
|
||||
}
|
||||
|
||||
|
@ -575,7 +575,17 @@ export function JSONDuplicate(
|
||||
}
|
||||
|
||||
/**
|
||||
* 用于复制或粘贴的时候重新生成
|
||||
* 用于复制或粘贴的时候重新生成组件id
|
||||
* 【备注】需考虑以下两类使用场景:
|
||||
* 1. 组件模板插入到页面中,组件模板含事件动作,事件动作中的componentId需替换成最新的;
|
||||
* 2. 页面中的复制&粘贴,复制的组件含事件动作,且componentId关联的是页面其他组件,此时无需重置componentId。
|
||||
* 【逻辑说明】
|
||||
* 1. 第一次遍历,确保重置所有组件id,并记录下当前所有组件的新旧id对应关系(reIds);
|
||||
* 2. 第一次遍历中,如果遇到事件动作,则将componentId替换成reIds中的新id,如果reIds中不存在对应的id,则重置componentId,并记录在reComptIds中;
|
||||
* 3. 完成第一次遍历后,检测reComptIds中是否存在reIds中没有的组件id(识别第2种场景),并将不在reIds种的id记录到resetComptIds,然后开始第二次遍历;
|
||||
* 4. 第二次遍历,恢复resetComptIds中的componentId。
|
||||
* 【额外说明】
|
||||
* 1. 仅第二类使用场景会触发第二次遍历,如果是第一类使用情况或者其他通用场景,则不会触发第二次遍历。
|
||||
* @param json
|
||||
*/
|
||||
export function reGenerateID(
|
||||
@ -583,21 +593,46 @@ export function reGenerateID(
|
||||
// 有时候复制时因为局部会有事件动作等内容,需要改为复制部分的新id,这里把老id与新id的关系存下来
|
||||
reIds: {[propKey: string]: string} = {}
|
||||
) {
|
||||
const reComptIds: {[propKey: string]: string} = {}; // 记录事件动作中的id
|
||||
JSONTraverse(json, (value: any, key: string, host: any) => {
|
||||
const isNodeIdFormat =
|
||||
typeof value === 'string' && value.indexOf('u:') === 0;
|
||||
if (key === 'id' && isNodeIdFormat && host) {
|
||||
const newID = generateNodeId();
|
||||
reIds[host.id] = newID;
|
||||
host.id = newID;
|
||||
}
|
||||
// 组件ID,给新的id内容
|
||||
else if (key === 'componentId' && isNodeIdFormat) {
|
||||
host.componentId = reIds[value] ?? value;
|
||||
if ((key === 'id' || key === 'componentId') && isNodeIdFormat && host) {
|
||||
if (reIds[value]) {
|
||||
host[key] = reIds[value];
|
||||
} else if (reComptIds[value]) {
|
||||
host[key] = reComptIds[value];
|
||||
reIds[value] = reComptIds[value];
|
||||
} else {
|
||||
const newID = generateNodeId();
|
||||
host[key] = newID;
|
||||
if (key === 'id') {
|
||||
reIds[value] = newID;
|
||||
} else if (key === 'componentId') {
|
||||
reComptIds[value] = newID;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
});
|
||||
|
||||
const resetComptIds: {[propKey: string]: string} = {};
|
||||
Object.keys(reComptIds).forEach((uidKey: string) => {
|
||||
if (!reIds[uidKey]) {
|
||||
resetComptIds[reComptIds[uidKey]] = uidKey; // 以新id为key
|
||||
}
|
||||
});
|
||||
|
||||
// 恢复resetComptIds中的componentId,避免事件动作失效
|
||||
JSONTraverse(json, (value: any, key: string, host: any) => {
|
||||
const isNodeIdFormat =
|
||||
typeof value === 'string' && value.indexOf('u:') === 0;
|
||||
if (key === 'componentId' && isNodeIdFormat && resetComptIds[value]) {
|
||||
host.componentId = resetComptIds[value];
|
||||
}
|
||||
return value;
|
||||
});
|
||||
return json;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user