/**
|
* 画布文字与业务属性的双向同步
|
* <p>
|
* 用户在画布内直接改文字,改的是组件的 content;在属性面板改值,改的是 data-qc-* 属性。
|
* 保存时以属性为准,不打通的话画布里的修改会在下一次保存时被静默丢弃。
|
*/
|
import type { Component, Editor } from 'grapesjs';
|
|
import { QUALITY_TYPE_ATTR, propAttrName } from './attrs';
|
import { buildQualityTraits } from './factory';
|
import { definitionOf } from './lookup';
|
|
/**
|
* 载入模板后重建属性面板字段。
|
* <p>
|
* traits 不参与 GrapesJS 项目数据的序列化,保存再打开时组件只剩框架自带的 id/title 两个字段,
|
* 这里按 data-quality-type 从注册表重建。属性值仍以组件上的 data-qc-* 为准
|
* (trait 初始化优先读组件属性,读不到才用默认值),所以不会把用户改过的值冲掉。
|
*/
|
export function restoreQualityTraits(editor: Editor): void {
|
editor
|
.getWrapper()
|
?.find(`[${QUALITY_TYPE_ATTR}]`)
|
.forEach((component) => {
|
const definition = definitionOf(component);
|
if (definition) {
|
component.setTraits(buildQualityTraits(definition));
|
}
|
});
|
}
|
|
export function bindQualityCanvasSync(editor: Editor): void {
|
// 画布内改文字 → 回写业务属性
|
editor.on('component:update:content', (component: Component) => {
|
const contentKey = definitionOf(component)?.contentKey;
|
if (!contentKey) {
|
return;
|
}
|
const text = component.get('content');
|
if (typeof text !== 'string') {
|
return;
|
}
|
const attrName = propAttrName(contentKey);
|
if (component.getAttributes()[attrName] === text) {
|
return;
|
}
|
component.addAttributes({ [attrName]: text });
|
});
|
|
// 属性面板改值 → 同步画布可见文字
|
editor.on('trait:value', ({ component, trait, value }) => {
|
const contentKey = definitionOf(component)?.contentKey;
|
if (!contentKey || typeof value !== 'string') {
|
return;
|
}
|
if (trait?.getName() !== propAttrName(contentKey)) {
|
return;
|
}
|
if (component.get('content') === value) {
|
return;
|
}
|
component.set('content', value);
|
});
|
}
|