多Tab页FormBuilder新增控件无法获取数据及报错问题求助
问题分析
- 变量作用域错误:循环中用
var j=0声明变量,由于var无块级作用域,所有异步的promise.then回调共享同一个j,最终执行时j值超出res数组索引范围,导致fb.actions.setData传入错误数据,FormBuilder实例初始化异常,引发getData is not a function错误。 - 未处理新增Tab页实例:点击
+ Page新增Tab页后,新创建的FormBuilder实例未加入fbInstances数组,新增控件的数据无法被收集。 - 重复调用tabs方法:循环中多次调用
$formPages.tabs(),造成不必要的性能损耗和状态混乱。
修复后的代码
前端JS代码
var $formPages = $("#survey"); var fbInstances = []; jQuery(($) => { "use strict"; obtenerEncuesta(); // 绑定新增Tab页点击事件 $("#add-page-tab a").click(function(e) { e.preventDefault(); addNewFormPage(); }); }); $formPages.tabs({ beforeActivate: function (event, ui) { if (ui.newPanel.selector === "#new-pageMostrar") { return false; } } }); function obtenerEncuesta() { $.ajax({ url: "../handler/Json_encuestas.ashx", type: "post", data: { acc: 'ObtenerEncuesta', idEncuesta: 1 }, dataType: 'json', success: function (data) { var res = jQuery.parseJSON(data.Json_Encuesta); var stepLen = res.length; for (let i = 1; i <= stepLen; i++) { const tabId = `pageMostrar-${i}`; const $newPageTemplate = document.getElementById("new-pageMostrar"); const $newTabTemplate = document.getElementById("add-page-tab"); // 克隆并初始化新Tab面板 const $newPage = $newPageTemplate.cloneNode(true); $newPage.setAttribute("id", tabId); $newPage.classList.add("fb-editor"); // 克隆并初始化新Tab标签 const $newTab = $newTabTemplate.cloneNode(true); $newTab.removeAttribute("id"); const $tabLink = $newTab.querySelector("a"); $tabLink.setAttribute("href", `#${tabId}`); $tabLink.innerText = `page ${i}`; // 插入DOM $newPageTemplate.parentElement.insertBefore($newPage, $newPageTemplate); $newTabTemplate.parentElement.insertBefore($newTab, $newPageTemplate); // 初始化FormBuilder并绑定数据 const formBuilder = $($newPage).formBuilder(); const targetData = res[i-1]; formBuilder.promise.then(function (fb) { fb.actions.setData(targetData); fbInstances.push(fb); }); } // 统一刷新tabs $formPages.tabs("refresh"); $formPages.tabs("option", "active", 0); }, error: function (err) { init_notificacion('error', 'Lipigas Informa!', "Problema al obtener documento asociado!"); } }); } // 新增Tab页逻辑 function addNewFormPage() { const pageNum = fbInstances.length + 1; const tabId = `pageMostrar-${pageNum}`; const $newPageTemplate = document.getElementById("new-pageMostrar"); const $newTabTemplate = document.getElementById("add-page-tab"); // 克隆面板 const $newPage = $newPageTemplate.cloneNode(true); $newPage.setAttribute("id", tabId); $newPage.classList.add("fb-editor"); // 克隆标签 const $newTab = $newTabTemplate.cloneNode(true); $newTab.removeAttribute("id"); const $tabLink = $newTab.querySelector("a"); $tabLink.setAttribute("href", `#${tabId}`); $tabLink.innerText = `page ${pageNum}`; // 插入DOM $newPageTemplate.parentElement.insertBefore($newPage, $newPageTemplate); $newTabTemplate.parentElement.insertBefore($newTab, $newTabTemplate); // 初始化FormBuilder并加入实例数组 const formBuilder = $($newPage).formBuilder(); formBuilder.promise.then(function(fb) { fbInstances.push(fb); }); // 刷新tabs并激活新页面 $formPages.tabs("refresh"); $formPages.tabs("option", "active", $formPages.tabs("length") - 2); } $("#save-all").click(function (e) { e.preventDefault(); var data = []; for (let i = 0; i < fbInstances.length; i++) { // 校验实例有效性,避免错误 if (fbInstances[i] && fbInstances[i].actions && typeof fbInstances[i].actions.getData === 'function') { data.push(fbInstances[i].actions.getData()); } } console.log(data); });
HTML代码
<div id="survey"> <ul id="tabs"> <li id="add-page-tab"><a href="#">+ Page</a></li> </ul> <div id="new-pageMostrar"></div> </div> <div class="save-all-wrap"><button id="save-all" type="button">Save All</button></div>
关键修复点
- 修复变量作用域:用
let声明循环变量,确保每个异步回调获取正确的res元素;直接使用i-1作为索引,避免依赖共享变量。 - 新增Tab页处理:添加
addNewFormPage方法,处理新增Tab逻辑,将新的FormBuilder实例加入fbInstances数组,确保新增控件数据可被收集。 - 优化tabs调用:将
tabs("refresh")移到循环外,避免重复调用;新增Tab后自动激活新页面。 - 实例有效性校验:在保存逻辑中先检查实例的
getData方法是否有效,避免抛出类型错误。
内容的提问来源于stack exchange,提问作者David Arancibia Godoy
相关产品推荐
相关产品推荐

