You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

多Tab页FormBuilder新增控件无法获取数据及报错问题求助

问题分析

  1. 变量作用域错误:循环中用var j=0声明变量,由于var无块级作用域,所有异步的promise.then回调共享同一个j,最终执行时j值超出res数组索引范围,导致fb.actions.setData传入错误数据,FormBuilder实例初始化异常,引发getData is not a function错误。
  2. 未处理新增Tab页实例:点击+ Page新增Tab页后,新创建的FormBuilder实例未加入fbInstances数组,新增控件的数据无法被收集。
  3. 重复调用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 09:11:31