【问题标题】:Javascript: Parsing JSON for tree view in HTMLJavascript:为 HTML 中的树视图解析 JSON
【发布时间】:2021-08-09 18:23:40
【问题描述】:

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

Expected result in HTML

    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"
   }
];

目前的功能是:

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 的顺序正确显示列表吗?非常感谢。

【问题讨论】:

  • 您的预期输出是什么?你目前的输出是多少?
  • 预期输出是解析当前 JSON 并在 HTML 中显示的函数。目前有:function CreateUlTreeView(items, parent){ var ul = document.createElement("ul"); if (parent) parent.appendChild(ul); items.forEach(function(x) { var li = document.createElement("li"); var text = document.createElement("span"); text.innerHTML = x.name; li.appendChild(text); if ( x.children && x.children.length>0) CreateUlTreeView(x.children, li); ul.append(li); });返回 ul; } var root = createTreeView(locations);
  • 请更新问题以包含您尝试实现的 HTML 输出示例。以及您当前获得的当前 HTML 输出。

标签: javascript html json parsing tree


【解决方案1】:

您应该与父 order 一起准备数据。如果你不能在后端做,你仍然可以即时计算。不仅仅是使用简单的递归函数来渲染树。

这是纯 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
&lt;div id="tree"&gt;&lt;/div&gt;

【讨论】:

    【解决方案2】:

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

    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)
    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;
    }
    &lt;ul id="tree"&gt;&lt;/ul&gt;

    【讨论】:

    • 非常感谢!如果整个树被扩展,任何方式如何将最后一个孩子的 + 符号更改为 - 符号?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-18
    • 2019-07-26
    • 1970-01-01
    • 1970-01-01
    • 2011-10-03
    相关资源
    最近更新 更多