如何在 Grapesjs 插件中触发 codemirror 'change' 事件

问题描述

我正在构建一个 Grapesjs 插件,并为按钮组件添加一个“jscript”特征,它显示代码镜像文本区域。这个想法是让用户能够编辑一些与按钮关联的 javascript 代码。我似乎无法拦截 codemirror 区域的 className="aClassName" 事件,至少,不是正确的 codemirror 特定版本。

令人高兴的是,当我编辑代码镜像区域并更改焦点时,常规的“更改”事件会触发我插件 change 中的 Grapejs onEvent 处理程序 - 很好。然后我可以将 codemirror 区域的内容存储到 trait 中。

editor.TraitManager.addType('jcodemirror-editor',{}

但是,如果我们在代码镜像区域中粘贴、退格或删除等操作,则永远不会发出常规的“更改”事件!

因此,我试图拦截更深层次的 codemirror 特定“更改”事件,该事件通常通过 onEvent({ elInput,component,event }) { let code_to_run = elInput.querySelector(".CodeMirror").CodeMirror.getValue() component.getTrait('jscript').set('value',code_to_run); }, 拦截并且触发更可靠(不幸的是,每次击键时也是如此)。如何连接此 codemirror 特定事件以触发通常的 cm.on("change",function (cm,changeObj) {} 代码

我的 https://jsfiddle.net/tcab/1rh7mn5b/ 中有一个解决方法,但想知道执行此操作的正确方法

我的插件

onEvent({ elInput,event }) {}

解决方法

根据 Grapesjs 关于特性 integrating external ui components 的官方文档,您可以通过调用 onEvent 手动触发 this.onChange(ev) 事件。

因此在 createInput 内,我继续拦截更可靠的 myCodeMirror.on("change",... 事件,并在该处理程序中手动触发 onEvent 即:

editor.TraitManager.addType('jcodemirror-editor',{
    createInput({ trait }) {
        const self = this  // SOLUTION part 1
        
        const el = document.createElement('div');
        el.innerHTML = `
            <form>
                <textarea id="myjscript" name="myjscript" rows="14">
                </textarea>
            </form>
        </div>
        `

        if (codemirrorEnabled) {
            const textareaEl = el.querySelector('textarea');
            var myCodeMirror = CodeMirror.fromTextArea(textareaEl,{
                mode: "javascript",lineWrapping: true,});

            myCodeMirror.on("change",function (cm,changeObj) {
                self.onChange(changeObj) // SOLUTION part 2
            })
        }

        return el;
    },