CKEditor4 dialog插件动态元素不刷新 选中元素属性展示遗留问题
问题根源
CKEditor 4 的 CKEDITOR.dialog.add 传入的工厂函数仅会在对话框首次初始化时执行1次,因此你原来写在工厂函数里的选中元素读取、属性列表生成逻辑只会跑一次,后续打开对话框不会重新执行,自然一直显示首次选中元素的属性列表。
修复方案
将选中元素读取、属性表单项生成、动态替换tab内容的逻辑全部移到 onShow 钩子中,保证每次打开对话框都会重新读取当前选中元素的属性,刷新表单内容。
修改后的完整代码如下:
// 对话框定义 CKEDITOR.dialog.add( 'abbrDialog', function( editor ) { return { // 对话框基础配置:标题、最小尺寸 title: 'Attributes', minWidth: 400, minHeight: 200, // 对话框内容定义 contents: [ { // 基础设置tab的id id: 'basic', // 初始留空,后续动态生成表单项 elements: [] } ], // 每次打开对话框都会触发该钩子 onShow: function() { // 1. 读取当前选中的元素 let selection = editor.getSelection(); let element = selection.getStartElement(); if (!element) return; // 无有效选中元素直接返回 let elAttributes = Object.keys(element.getAttributes()); // 2. 生成对应属性的表单项列表 let listAttrElements = getListOfItems(elAttributes); // 3. 替换basic tab的表单配置 let basicTabDef = this.definition.contents.find(item => item.id === 'basic'); basicTabDef.elements = listAttrElements; // 4. 清空旧的控件缓存,重绘对话框 this._.contents.basic = {}; this.setupContent(element); this.layout(); }, // 用户点击确认按钮时触发 onOk: function() { let selection = editor.getSelection(); let element = selection.getStartElement(); // 提交所有表单项的修改到选中元素 this.commitContent(element); CKEDITOR.dialog.getCurrent().reset(); }, // 对话框首次加载完成触发 onLoad: () => { console.log('loaded') } }; }); // 生成属性勾选表单项的工具函数 function getListOfItems (attrObj) { return attrObj.map ((el) => { return { type: 'checkbox', id: el, // 用属性名作为id,避免索引冲突 label: el, // 对话框初始化时赋值 setup: function( element ) { // 读取元素对应属性的状态赋值给勾选框 this.setValue(!!element.getAttribute(el)); }, // 确认提交时写入属性 commit: function( element ) { if (this.getValue()) { element.setAttribute(el, el); } else { element.removeAttribute(el); } } } }); }
补充说明
- 原代码表单项用索引作为id,已调整为用属性名作为id,避免不同属性数量的元素切换时出现ID冲突
- 原代码中
setup、commit钩子内的getText是读取元素文本的错误写法,已调整为属性读写逻辑,可根据自身业务需求修改赋值规则
内容的提问来源于stack exchange,提问作者M. Salah Lahori
相关产品推荐
相关产品推荐

