使用JS从扁平数据构建树形JSON适配SAP UI5树表格
问题:SAP UI5中扁平角色数据转树形结构的通用实现
原始数据
roles: [ { role: 'JLP', desc: "jlp role", query:"q1" }, { role: 'JLP', desc: "jlp role", query:"q2" }, { role: 'JLP', desc: "jlp role", query:"q3" }, { role: 'DJF', desc: "djf role", query:"q1" }, { role: 'DJF', desc: "djf role", query:"q2" }, { role: 'CJ', desc: "CJ role", query:"q1" } ]
期望树形结构
{ "roles": [ { "rolename": "JLP", "properties": [ { "role": "JLP", "desc": "jlp role", "query": "q1" }, { "role": "JLP", "desc": "jlp role", "query": "q2" }, { "role": "JLP", "desc": "jlp role", "query": "q3" } ] }, { "rolename": "DJF", "properties": [ { "role": "DJF", "desc": "djf role", "query": "q1" }, { "role": "DJF", "desc": "djf role", "query": "q2" } ] }, { "rolename": "CJ", "properties": [ { "role": "CJ", "desc": "cj role", "query": "q1" } ] } ] }
当前实现与问题
当前先构建了角色结构:
buildData:function(o){ //find all types of roles var unique= []; for(i = 0; i < o.length; i++){ var rolename = o[i].role; if(unique.indexOf(rolename)< 0) unique.push(rolename); } //create data structure var datForm ={results:{roles:[]}}; var prop = {rolename:"", properties:[]}; unique.forEach(function(a,index){ prop.rolename = a datForm.results.roles.push(prop) prop = {rolename:"", properties:[]}; });
但在填充数据时,不得不硬编码数组索引匹配角色,导致代码无法适配角色数量变化的场景:
for(i = 0; i < o.length; i++){ var current = o[i].role; var segment = o[i]; if(current === datForm.results.roles[0].rolename) datForm.results.roles[0].properties.push(segment) if(current === datForm.results.roles[1].rolename) datForm.results.roles[1].properties.push(segment) if(current === datForm.results.roles[2].rolename) datForm.results.roles[2].properties.push(segment) } //console.log(datForm) var oModel = this.getView().getModel(); oModel.setData(datForm) this.getView().byId("TreeTableBasic").bindRows("/results")
通用实现方案
可以利用对象映射的方式实现一次遍历完成分组,彻底避免硬编码索引的问题,代码更简洁且适配任意数量的角色:
buildData: function(o) { // 用对象做映射,快速定位对应角色的分组 const roleGroupMap = {}; o.forEach(item => { const roleName = item.role; // 如果当前角色还未创建分组,初始化分组结构 if (!roleGroupMap[roleName]) { roleGroupMap[roleName] = { rolename: roleName, properties: [] }; } // 将当前数据项推入对应分组的properties数组 roleGroupMap[roleName].properties.push(item); }); // 将映射对象的value转为数组,构建最终数据结构 const datForm = { results: { roles: Object.values(roleGroupMap) } }; // 绑定数据到模型与树表格 const oModel = this.getView().getModel(); oModel.setData(datForm); // 修正绑定路径,确保指向roles数组 this.getView().byId("TreeTableBasic").bindRows("/results/roles"); }
方案优势
- 仅需一次遍历原始数据,执行效率更高;
- 自动适配任意数量的角色类型,无需修改代码;
- 代码结构更简洁,可读性更强;
- 修正了原代码中树表格绑定路径的问题,确保数据正确渲染。
内容的提问来源于stack exchange,提问作者user3369908
相关产品推荐
相关产品推荐

