简体   繁体   English

如何遍历和渲染表示嵌套树的实例化路径数组中的嵌套HTML?

[英]How to traverse and render nested HTML from an materialized path array which represents nested tree?

I've an array which frontend React component received after AJAX call. 我有一个数组,在AJAX调用之后,前端React组件收到了一个数组。 This array is nothing but annotated list sent from backend which represents Django-Treebeard model data. 该数组不过是从后端发送的带注释的列表,该列表表示Django-Treebeard模型数据。 Annotated list is a materialized path tree which structures all nodes of nested tree in the form of flat array. 带注释的列表是物化路径树,它以平面数组的形式构造嵌套树的所有节点。

Below is the exact data available in front-end react: 以下是前端反应中可用的确切数据:

const data = [
  {
    info: { close: [], open: true, level: 1 },
    spot: {
      id: 2,
      path: "00020002",
      depth: 2,
      numchild: 0,
      landmark_name: "Metrolink Trafford Depot",
      distance: "700.00",
      unit: "m",
      child: 0
    }
  },
  {
    info: { close: [], open: false, level: 1 },
    spot: {
      id: 3,
      path: "00020003",
      depth: 2,
      numchild: 0,
      landmark_name: "Bus Stand",
      distance: "300.00",
      unit: "m",
      child: 0
    }
  },
  {
    info: { close: [], open: false, level: 1 },
    spot: {
      id: 4,
      path: "00020005",
      depth: 2,
      numchild: 2,
      landmark_name: "Restaurants and Bars",
      distance: null,
      unit: null,
      child: 1
    }
  },
  {
    info: { close: [], open: true, level: 2 },
    spot: {
      id: 5,
      path: "000200050001",
      depth: 3,
      numchild: 2,
      landmark_name: "Trafford Bar",
      distance: 650.00,
      unit: "m",
      child: 1
    }
  },
  {
    info: { close: ["0"], open: false, level: 2 },
    spot: {
      id: 6,
      path: "000200050003",
      depth: 3,
      numchild: 0,
      landmark_name: "Café Hardrock",
      distance: "1.50 ",
      unit: "km",
      child: 0
    }
  },
  {
    info: { close: [], open: false, level: 1 },
    spot: {
      id: 8,
      path: "00020008",
      depth: 2,
      numchild: 1,
      landmark_name: "Hospital",
      distance: null,
      unit: null,
      child: 1
    }
  },
  {
    info: { close: ["0", "1", "2"], open: true, level: 2 },
    spot: {
      id: 14,
      path: "000200080001",
      depth: 3,
      numchild: 0,
      landmark_name: "Seymour Grove Health Centre",
      distance: "320.00",
      unit: "m",
      child: 0
    }
  }
];

The actual data tree in the back-end is: 后端中的实际数据树为:

Root
|_ Metrolink Trafford Depot: 700m
|_Bus Stand: 300 
|_Restaurant and Bars:
  |_Trafford Bar : 650m
  |_ Café Hardrock: 1.5km
|_ Hospital:
  |_ Seymour Grove Health Centre: 320m

I want to create nested div structure representing above hierarchy as below: 我想创建表示上面的层次结构的嵌套div结构,如下所示:

<div>
    <h3> MetroLink Trafford Depot :</h3>
    <p> 700m </p>
</div>
<div>
    <h3> Bus Stand:</h3>
    <p>300m </p>
</div>
<div>
    <h3> Restaurants and Bars:</h3>
        <div>
            <h4> Trafford Bar:</h4>
            <p> 650m</p>
        </div>
        <div>
            <h4> Café Hardrock:</h4>
            <p> 1.5km</p>
        </div>
</div>
<div>
    <h3> Hospital:</h3>
        <div> 
            <h4> Seymour Grove Health Centre:</h4>
            <p>320m</p>
        </div>
</div>

I've tried recursion but failed miserably. 我尝试过递归,但失败了。 Not even close to what I intended. 甚至没有达到我的预期。 I tried to search third party solutions but they require completely different structure of data. 我尝试搜索第三方解决方案,但它们需要完全不同的数据结构。 I don't want to change structure of data in the backend. 我不想更改后端的数据结构。 It's another hell I just came out through. 这是我刚经历的另一个地狱。 In addition, I think materialized path tree is better suited for backend efficiency. 另外,我认为物化路径树更适合后端效率。

How can I write React component to generate above HTML structure from given data? 如何编写React组件以根据给定数据生成上述HTML结构?

You could first create a nested object structure from it, using the path property (split it in chunks of 4 characters). 您可以首先使用path属性从中创建一个嵌套的对象结构(将其拆分为4个字符的块)。 Once you have that, you can use recursion to create the HTML elements: 一旦有了它,就可以使用递归来创建HTML元素:

 class Tree extends React.Component { constructor(props) { super(props); this.state = { data: props.data } } render() { // Create nested tree structure from data let root = { children: {} }; for (let {spot} of this.state.data) { let node = root; for (let child of spot.path.match(/..../g)) { if (!(child in node.children)) node.children[child] = { children: {} }; node = node.children[child]; } node.name = spot.landmark_name; if (spot.distance) node.distance = String(+spot.distance) + spot.unit; } // Create elements from tree const e = React.createElement; return (function recur(node, level=1) { let children = Object.values(node.children).map(child => recur(child, level+1)); if (children.length === 1 && !node.name) return children[0]; if (!children.length) children = [e("p", null, node.distance)]; if (node.name) children.unshift(e("h" + level, null, node.name)); return e("div", null, ...children); })(root); } } // Sample data from the question: const data = [{info: { close: [], open: true, level: 1 },spot: {id: 2,path: "00020002",depth: 2,numchild: 0,landmark_name: "Metrolink Trafford Depot",distance: "700.00",unit: "m",child: 0}},{info: { close: [], open: false, level: 1 },spot: {id: 3,path: "00020003",depth: 2,numchild: 0,landmark_name: "Bus Stand",distance: "300.00",unit: "m",child: 0}},{info: { close: [], open: false, level: 1 },spot: {id: 4,path: "00020005",depth: 2,numchild: 2,landmark_name: "Restaurants and Bars",distance: null,unit: null,child: 1}},{info: { close: [], open: true, level: 2 },spot: {id: 5,path: "000200050001",depth: 3,numchild: 2,landmark_name: "Trafford Bar",distance: 650.00,unit: "m",child: 1}},{info: { close: ["0"], open: false, level: 2 },spot: {id: 6,path: "000200050003",depth: 3,numchild: 0,landmark_name: "Café Hardrock",distance: "1.50 ",unit: "km",child: 0}},{info: { close: [], open: false, level: 1 },spot: {id: 8,path: "00020008",depth: 2,numchild: 1,landmark_name: "Hospital",distance: null,unit: null,child: 1}},{info: { close: ["0", "1", "2"], open: true, level: 2 },spot: {id: 14,path: "000200080001",depth: 3,numchild: 0,landmark_name: "Seymour Grove Health Centre",distance: "320.00",unit: "m",child: 0}}]; // Render ReactDOM.render(React.createElement(Tree, {data}), document.body); 
 div, p { margin-left: 20px } 
 <script crossorigin src="https://unpkg.com/react@16/umd/react.production.min.js"></script> <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何根据 javascript 中的数组中的路径遍历嵌套的 object? - How to traverse a nested object based on a path in an array in javascript? 如何从嵌套的 object 树中获取路径 - How to get A Path from a nested object tree JS:在嵌套数组中添加和删除元素,这些元素代表表数据 - JS: Adding and removing elements in nested array, which represents table data 如何使用jQuery使用div将JSON树呈现为嵌套HTML? - How to use jQuery to render a JSON tree as nested HTML using divs? 从数组中的键遍历嵌套的地图/对象 - Traverse nested maps / objects from keys in an array 如何将节点数组对象展开为表示目录结构的嵌套对象 - How to unflatten a nodes array object to a nested object which represents a directory structure 如何遍历树状未知深度的嵌套数据结构以查找和收集可寻址数组项? - How to traverse through a tree like nested data structure of unknown depth in order to find and collect addressable array items? 如何遍历嵌套数据 - How to traverse nested data 如何获取 html 嵌套结构与 ul,li 用于树数据数组 - How to get html nested structure with ul, li for a tree data array 如何从 JavaScript 中的 JSON 树获取嵌套的父路径? - How to get nested parent path from a JSON tree in JavaScript?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM