首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Javascript:解析JSON以获取HTML中的树视图

Javascript:解析JSON以获取HTML中的树视图
EN

Stack Overflow用户
提问于 2021-05-20 21:32:57
回答 2查看 356关注 0票数 0

尝试解析以下格式的JSON以递归获取父子树,并将其处理为在HTML中显示可单击的列表

Expected result in HTML

代码语言:javascript
复制
    var data = [
   {
      "name":"Level 1",
      "sys_id":"3b8a6ea81bd034d0d1dcb9118b4bcb9a",
      "order":"01"
   },
   {
      "name":"L1-1",
      "sys_id":"565b226c1bd034d0d1dcb9118b4bcbb2",
      "order":"01.01"
   },
   {
      "name":"Level 2",
      "sys_id":"ca49eea01bd034d0d1dcb9118b4bcb17",
      "order":"02"
   },
   {
      "name":"L2-2",
      "sys_id":"e699e2641bd034d0d1dcb9118b4bcb84",
      "order":"02.02"
   },
   {
      "name":"L2-2-1",
      "sys_id":"15da66e81bd034d0d1dcb9118b4bcb1c",
      "order":"02.02.01"
   },
   {
      "name":"L2-2-1-1",
      "sys_id":"5a2baa2c1bd034d0d1dcb9118b4bcb63",
      "order":"02.02.01.01"
   }
];

现在的当前函数是:

代码语言:javascript
复制
function createTreeView(data) {
  var tree = [],
    object = {},
    parent,
    child;

  for (var i = 0; i < data.length; i++) {
    parent = data[i];

    object[parent.id] = parent;
    object[parent.id]["children"] = [];
  }

  for (var id in object) {
    if (object.hasOwnProperty(id)) {
      child = object[id];      
      if (child.parentId && object[child["parentId"]]) {
        object[child["parentId"]]["children"].push(child);
      } else {
        tree.push(child);
      }
    }
  }
  return tree;
}

我可以得到你的帮助吗?如何正确地根据JSON的顺序显示列表?非常感谢。

EN

回答 2

Stack Overflow用户

发布于 2021-05-20 22:45:15

您应该使用父order准备数据。如果你不能在后端做到这一点,你仍然可以动态地计算它。而不是仅仅使用简单的递归函数来渲染树。

下面是纯JavaScript示例

代码语言:javascript
复制
const data = [
   {
      "name":"Level 1",
      "sys_id":"3b8a6ea81bd034d0d1dcb9118b4bcb9a",
      "order":"01"
   },
   {
      "name":"L1-1",
      "sys_id":"565b226c1bd034d0d1dcb9118b4bcbb2",
      "order":"01.01"
   },
   {
      "name":"Level 2",
      "sys_id":"ca49eea01bd034d0d1dcb9118b4bcb17",
      "order":"02"
   },
   {
      "name":"L2-2",
      "sys_id":"e699e2641bd034d0d1dcb9118b4bcb84",
      "order":"02.02"
   },
   {
      "name":"L2-2-1",
      "sys_id":"15da66e81bd034d0d1dcb9118b4bcb1c",
      "order":"02.02.01"
   },
   {
      "name":"L2-2-1-1",
      "sys_id":"5a2baa2c1bd034d0d1dcb9118b4bcb63",
      "order":"02.02.01.01"
   }
];

function createTree(data) {
  const nodeWithParent = []
  
  // Find the parent for each node
  data.forEach(d => {
    const parent = d.order.includes('.')?d.order.substr(0, d.order.lastIndexOf('.')):null
    nodeWithParent.push({...d, parent})
  })
  
  // Recursive function to create HTML out of node
  function getNodeHtml(n) {
    const children = nodeWithParent.filter(d => d.parent === n.order)
    let html = '<li>' + n.name 
    if(children.length>0) {
      html += '<ul>' 
        + children.map(getNodeHtml).join('')
        + '</ul>'
    }
    html += '</li>'
    return html
  }
  
  // Get all root nodes (without parent)
  const root = nodeWithParent.filter(d => d.parent === null)
  
  return root.map(getNodeHtml).join('')
}

const html = createTree(data)
document.getElementById('tree').innerHTML = html
代码语言:javascript
复制
<div id="tree"></div>

票数 1
EN

Stack Overflow用户

发布于 2021-05-21 00:01:46

我修改了奥列格的解决方案,以包含您正在寻找的可折叠的树行为。它使用带有一些额外格式的this basic example from w3schools来添加带框的加号和减号:

代码语言:javascript
复制
const data = [
   {
      "name":"Level 1",
      "sys_id":"3b8a6ea81bd034d0d1dcb9118b4bcb9a",
      "order":"01"
   },
   {
      "name":"L1-1",
      "sys_id":"565b226c1bd034d0d1dcb9118b4bcbb2",
      "order":"01.01"
   },
   {
      "name":"Level 2",
      "sys_id":"ca49eea01bd034d0d1dcb9118b4bcb17",
      "order":"02"
   },
   {
      "name":"L2-2",
      "sys_id":"e699e2641bd034d0d1dcb9118b4bcb84",
      "order":"02.02"
   },
   {
      "name":"L2-2-1",
      "sys_id":"15da66e81bd034d0d1dcb9118b4bcb1c",
      "order":"02.02.01"
   },
   {
      "name":"L2-2-1-1",
      "sys_id":"5a2baa2c1bd034d0d1dcb9118b4bcb63",
      "order":"02.02.01.01"
   }
];

function createTree(data) {
  const nodeWithParent = []
  
  // Find the parent for each node
  data.forEach(d => {
    const parent = d.order.includes('.')?d.order.substr(0, d.order.lastIndexOf('.')):null
    nodeWithParent.push({...d, parent})
  })
  
  // Recursive function to create HTML out of node
  function getNodeHtml(n) {
    const children = nodeWithParent.filter(d => d.parent === n.order)
    let html = '<li><span class="box">' + n.name + '</span><ul class="nested">'
    if(children.length>0) {
      html += '<li>' 
        + children.map(getNodeHtml).join('')
        + '</li>'
    }
    html += '</ul></li>'
    return html
  }
  
  // Get all root nodes (without parent)
  const root = nodeWithParent.filter(d => d.parent === null)
  
  return root.map(getNodeHtml).join('')
}

const html = createTree(data)
let tree = document.getElementById('tree');
tree.innerHTML = html
console.log(tree)

var toggler = document.getElementsByClassName("box");
var i;

for (i = 0; i < toggler.length; i++) {
  toggler[i].addEventListener("click", function() {
    console.log(this.parentElement)
    this.parentElement.querySelector(".nested").classList.toggle("active");
    this.classList.toggle("check-box");
  });
}
console.log(toggler)
代码语言:javascript
复制
ul, #tree {
  list-style-type: none;
}

li, #tree {
  font-size: 20px;
}

.box {
  cursor: pointer;
  -webkit-user-select: none; /* Safari 3.1+ */
  -moz-user-select: none; /* Firefox 2+ */
  -ms-user-select: none; /* IE 10+ */
  user-select: none;
  padding: 0px 0px;
  display: flex;
  align-items: center;
}

.box::before {
  font-size: 10px;
  font-family: "Courier New", monospace;
  content: "+";
  width: 10px;
  height: 10px;
  text-align: center;
  vertical-align: center;
  display: inline-block;
  border-style: solid;
  border-width: 1pt;
  margin-right: 5px;
}

.check-box::before {
  content: "-"; 
}

.nested {
  display: none;
}

.active {
  display: block;
}
代码语言:javascript
复制
<ul id="tree"></ul>

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67621375

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档