如何将四层嵌套JSON的叶子节点补充上层数据适配Tabulator.js?
解决嵌套JSON转扁平数组适配Tabulator.js的问题
我明白你现在的困扰——Tabulator.js对嵌套数组的支持确实有限,层级访问 notation 没法处理数组遍历的场景,所以必须先把嵌套结构转成扁平的对象数组才行。不用把数据存成文件,不管是前端直接处理还是后端预处理,都能直接把扁平数组传给Tabulator,下面给你具体的实现方案:
前端JavaScript递归实现(推荐,直接适配Tabulator)
因为Tabulator是前端表格库,直接在前端处理数据最直接,不用绕后端。核心思路是用递归遍历嵌套结构,把每一层的非数组数据作为"上下文"传递下去,遇到最内层的termine数组时,就把每个元素和上下文合并成新对象,收集到结果数组里。
举个代码示例,假设你的原始数据结构是这样的:
const rawData = { // 顶层非数组属性 schoolName: "XX职业学院", year: 2024, ausbildungen: [ { // ausbildungen层非数组属性 ausbildungName: "机电一体化", code: "MECH-01", kurse: [ { // kurse层非数组属性 kursName: "机械设计基础", teacher: "张老师", termine: [ { date: "2024-05-10", time: "09:00-11:00", room: "A101" }, { date: "2024-05-17", time: "09:00-11:00", room: "A101" } ] } ] } ] };
对应的递归扁平化函数:
function flattenNestedData(data, context = {}) { let result = []; // 先把当前层的非数组属性合并到上下文 const currentContext = { ...context }; Object.keys(data).forEach(key => { if (!Array.isArray(data[key])) { currentContext[key] = data[key]; } }); // 遍历当前层的数组属性 Object.keys(data).forEach(key => { if (Array.isArray(data[key])) { if (key === "termine") { // 遇到最内层的termine数组,每个元素合并上下文 data[key].forEach(item => { result.push({ ...currentContext, ...item }); }); } else { // 其他数组(ausbildungen、kurse)递归处理 data[key].forEach(item => { result = result.concat(flattenNestedData(item, currentContext)); }); } } }); return result; } // 调用函数得到扁平数组 const flatData = flattenNestedData(rawData);
然后直接把flatData传给Tabulator:
new Tabulator("#example-table", { data: flatData, // 这里用扁平化后的数组 columns: [ { title: "学校", field: "schoolName" }, { title: "年份", field: "year" }, { title: "专业", field: "ausbildungName" }, { title: "课程", field: "kursName" }, { title: "日期", field: "date" }, // 其他列... ] });
后端PHP递归实现(如果需要后端预处理)
如果你还是想在PHP端处理,下面是一个可行的递归实现,思路和前端一致:
function flattenNestedData($data, $context = []) { $result = []; $currentContext = $context; // 合并当前层非数组属性到上下文 foreach ($data as $key => $value) { if (!is_array($value)) { $currentContext[$key] = $value; } } // 遍历数组属性 foreach ($data as $key => $value) { if (is_array($value)) { if ($key === "termine") { foreach ($value as $item) { $result[] = array_merge($currentContext, $item); } } else { foreach ($value as $item) { $result = array_merge($result, flattenNestedData($item, $currentContext)); } } } } return $result; } // 假设$rawData是从服务器获取的JSON解码后的数组 $flatData = flattenNestedData($rawData); // 然后把$flatData转成JSON返回给前端,直接给Tabulator用 echo json_encode($flatData);
关键说明
- 不需要把数据存为文件:不管前端还是后端处理,处理后的扁平数组都可以直接作为Tabulator的数据源,前端直接用JavaScript数组,后端返回JSON即可。
- 递归函数的通用性:这个递归逻辑可以适配你的四层嵌套结构,如果后续结构有调整,只要修改判断最内层数组的条件(
key === "termine")即可。
内容的提问来源于stack exchange,提问作者dubiousa
相关产品推荐
相关产品推荐

