Summernote动态添加按钮时如何传递自定义参数?
解决Summernote动态自定义按钮中传入遍历数据与context参数冲突的问题
你的问题核心有两个:一是循环中var声明变量导致的闭包陷阱,二是直接传递field会覆盖Summernote按钮函数默认接收的context参数。下面是具体的解决方法:
问题分析
- 闭包陷阱:用
var声明的field在循环结束后会保留最后一次循环的值,所有按钮的点击事件都会引用这个最终值,而非各自对应的字段。 - 参数覆盖:Summernote的按钮渲染函数默认会接收
context作为参数,如果你直接把field作为参数传入并立即执行函数,会把context的位置替换成field,导致上下文丢失。
解决方案
使用**立即执行函数表达式(IIFE)**在每次循环中创建独立作用域,捕获当前的field值,同时返回一个接收context的函数,这样既能保留Summernote的上下文,又能正确绑定当前循环的字段数据。
修改循环内的按钮定义部分:
var formButtons = {}; var formButtonIds = []; if(FormsModule.currentForm) { for(var i=0; i<FormsModule.currentForm.fields.length; i++) { var field = FormsModule.currentForm.fields[i]; var fieldId = 'button_' + i; // 用IIFE捕获当前循环的field值 formButtons[fieldId] = (function(currentField) { // 返回接收context的函数,供Summernote调用 return function(context) { console.log(context); // 正常输出Summernote上下文 console.log(currentField); // 输出当前循环对应的字段 var ui = $.summernote.ui; var tooltip = 'Insert ' + currentField.title; // 创建按钮 var button = ui.button({ contents: HelperModule.getTitle(currentField.title), tooltip: tooltip, click: function () { context.invoke("editor.insertText", '<span class="field-input-button">#' + currentField.title + '#</span>'); }, }); return button.render(); }; })(field); // 传入当前循环的field formButtonIds.push(fieldId); } }
代码说明
- IIFE会在每次循环时执行,把当前的
field作为参数传入,在独立作用域中保存为currentField,避免后续循环修改导致的闭包问题。 - 返回的函数专门接收Summernote传入的
context参数,这样context和当前字段currentField都能被正确访问。 - 点击事件中使用
currentField而非原来的field,确保每个按钮绑定的是各自对应的字段数据。
剩下的Summernote初始化代码保持不变即可,现在每个动态按钮都能正确获取到对应的字段数据,同时正常使用context调用编辑器的API。
内容的提问来源于stack exchange,提问作者Mats Raemen
相关产品推荐
相关产品推荐

