陷入一个逻辑问题。如何遍历具有未知嵌套数组的 json 树?

Stuck in a logical problem. How do I loop through a json tree having unknown nested arrays?

我必须构建一个图表类的东西,其中我有一个 json 树的输出。此 json 树将具有多个未知级别的嵌套数组。我无法遍历这些 json 数组,因为我无法构建 'for loop'.

这里我的逻辑如何,我的 HTML 代码将如何?

我发现了一些重复的问题,但没有正确回答或者我还不够成熟,无法理解它们。

这是我正在处理的 JSON 结构:

{
  "name": "TEST",
  "children": [
    {
      "title": "a",
      "description": "a",
      "children": [
        {
          "title": "b1",
          "description": "b1",
          "children": [
            {
              "title": "c1",
              "description": "c1",
              "children": [
                {
                  "title": "e1",
                  "description": "e1",
                  "children": []
                }
              ]
            },
            {
              "title": "d2",
              "description": "d2",
              "children": []
            }
          ]
        },
        {
          "title": "b2",
          "description": "b2",
          "children": []
        }
      ]
    }
  ]
}

图像显示了预期的输出。我也试图在 angular 7 中实现这一点。

你应该为此使用递归函数。

HTML

<div #parent></div>

TypeScript

我建议使用两种方法来实现这一点。你可以使用其中之一。

1.在递归函数中使用 for 循环。

import { Component,ViewChild,ElementRef } from '@angular/core';

@Component({...})
export class AppComponent  {

    myObj = {...};
    @ViewChild('parent') d1:ElementRef;
    constructor() {}

    createArrayUsingFor() {
      let recursiveFn = (obj) => {

        for (let i = 0 ; i < obj.children.length; i++) {

          const html = `<div><p>${obj.children[i].title}</p><p>${obj.children[i].description}</p></div>`
          this.d1.nativeElement.insertAdjacentHTML('beforeend', html);

          if (obj.children[i].children.length > 0) {

            recursiveFn(obj.children[i]);
          }
        }
      }
      recursiveFn(this.myObj);
    }

    ngAfterViewInit() {
      this.createArrayUsingFor();
    }
}

2。在递归函数中使用 map 函数。

import { Component,ViewChild,ElementRef } from '@angular/core';

@Component({...})
export class AppComponent  {

    myObj = {...};
    @ViewChild('parent') d1:ElementRef;
    constructor() {}

    createArrayUsingMap() {
      let recursiveFn = (obj) => {

        if (obj.title && obj.description) {
          const html = `<div><p>${obj.title}</p><p>${obj.description}</p></div>`
          this.d1.nativeElement.insertAdjacentHTML('beforeend', html);
        }

        obj.children.map(recursiveFn)
      }
      recursiveFn(this.myObj);
    }

    ngAfterViewInit() {
      this.createArrayUsingMap();
    }
}

在这里找到工作StackBlitz

注意:如果你需要很好的html结构,就像你问题中的图片,你需要定义一个级别对于数组中的每个 object(每个 children 的每个 child),您需要根据该级别设置样式。例如,根据 级别 .

为每个 div 设置 margin-left

您将需要递归地执行此操作。

您需要做的第一件事是创建一个自定义组件,我们将在该组件中递归地在模板中显示您的数据。该组件将检查当前迭代中是否存在 children,如果存在,它将通过传入 children 数据来调用自身。

递归组件中的模板如下所示

<ul *ngFor="let detail of details">
    <li>
        <div>
            Title: {{detail.title}}
            <br />
            Description: {{detail.description}}
        </div>
        <test *ngIf="detail.children" [details]="detail.children"></test>
    </li>
</ul>

然后在您的父组件中,您只需调用传入初始数据的递归组件(对您来说是 data.children,其中 data 是 OP 中的示例 JSON) .

这是 StackBlitz 上的一个工作示例。