如何使用 angularjs 中嵌套 JSON 的缩进创建 table

How to create a table with indents from nested JSON in angularjs

我从 API 调用中得到一个嵌套的 JSON 对象,它看起来类似于以下内容:

{
  "name": “Main “Folder”,
  "children": [
    {
      "name": “Child Folder 1”,
      "children": []
    },
    {
      "name": “Child Folder 2”,
      "children": [
        {
          "name": “Sub Folder 1”,
          "children": [
            {
                “name”: “Sub Sub Folder 1”,
                “children”: []
            }
          ]
        },
        {
          "name": “Sub Folder 2” ,
          "children": []
        }
      ]
    }
  ]
}

JSON 对象可以嵌套多远没有限制,所以我不知道。我需要在 table 中将所有子文件夹缩进到父文件夹下。我什至不确定该怎么做。我尝试的第一件事是在我的 HTML 文件中做类似的事情,但我很快意识到它不会起作用。

folders.html

<table>
    <thead>
        <tr><strong>{{ this.tableData.name }}</strong></tr>
    </thead>
    <tbody ng-repeat="b in this.tableData.children">
        <tr>
            <td>{{ b.name }}</td>
            <td ng-repeat="c in b.children">{{ c.name }}</td>
        </tr>
    </tbody>
</table>

folders.js

export default class FoldersController {
  constructor($rootScope, $scope, $uibModal) {
      this.tableData = {Example Data from top}
  }
}

有没有不太复杂的方法可以做到这一点?谢谢!

您应该使用包含 table 的模板创建一个组件,然后您可以将您的组件嵌套在自身内部以遵循树结构逻辑路径:

您的根控制器应包含您的 table 数据:

angular.module('app').controller('RootCtrl', ['$scope', function($scope) {
    // assigning the data to $scope to make it available in the view
    $scope.tableData = {Example Data from top};
}]);

你的树组件可能是这样的:

angular.module('app').component('treeComponent', {
    controller: 'TreeCtrl',
    bindings: {
        tree: '<',
    },
    templateUrl: 'tree-view.html'
});

您的根模板应加载组件的第一个实例:

<div>
   <tree-component tree="tableData"></tree-component>
</div>

然后组件模板应该在需要时处理递归; tree-view.html:

<table class="record-table">
    <thead>
        <tr>
           <th>
              <strong>{{ $ctrl.tableData.name }}</strong>
           </th> 
        </tr>
    </thead>
    <tbody>
        <tr ng-repeat="node in $ctrl.tableData.children">
            <td>{{node.name}}</td>
            <td ng-if="node.children.length > 0">
               <tree-component tree="node.children"></tree-component>
            </td>
        </tr>
    </tbody>
</table>

然后使用基本的 css:

创建缩进就变得容易了
.record-table .record-table {
   padding-left: 20px
}

我能够在 js 文件中使用递归找出我自己的解决方案。我也实现了 mindthefrequency 的答案,它似乎工作得很好。我将其标记为最佳答案,因为它似乎是更简洁的解决方案,但我发布了我所拥有的内容,以防有人想要采用更面向 js 的方法。

首先,在 js 文件中,使用递归将所有节点以及每个节点需要缩进的距离添加到 table 数据变量。

folders.js

export default class FoldersController {
  constructor($rootScope, $scope, $uibModal) {
      this.resp = {Example Data from top}
      this.tableData = []
      this.createTable(this.resp.children, 0, [
          {
            name: this.resp.name,
            indent: '0px',
          },
        ]);
  }

  createTable(children, count, data) {
    count += 1;

    // base case
    if (!children || children.length === 0) {
      return;
    }

    for (const child of children) {
      const { name } = child;

      const returnData = data;
      returnData.push({
        name: name,
        indent: `${count * 25}px`,
      });

      this.tableData = returnData;

      this.createTable(child.children, count, returnData);
    }
  }
}

然后,在html文件中,使用angularjs正确缩进每个节点

folders.html

<table>
  <thead>
    <tr><strong>Table Header</strong></tr>
  </thead>
  <tbody ng-repeat="b in vm.tableData">
    <tr>
      <td ng-style="{'padding-left': b.indent}">{{ b.name }}</td>
    </tr>
  </tbody>
</table>