AngularJS - Json 到树结构

AngularJS - Json to Tree structure

我见过很多将 Json 响应转为 Ul 树结构的答案。 问题是所有这些主题都围绕着一个嵌套的响应指向 parent object 和 child object.

之间的关系

我有一个非嵌套的 Json 响应,通过引用 object 来指示关系 属性。

以下为部分回复:

{"id":"1","parent_id":null,"name":"Item-0"}, {"id":"2","parent_id":"1","name":"Item-1"}, {"id":"3","parent_id":"2","name":"Item-2"}, {"id":"4","parent_id":"2","name":"Item-4"}, {"id":"5","parent_id":"2","name":"Item-5"}, {"id":"6","parent_id":"2","name":"Item-6"}, {"id":"7","parent_id":"2","name":"Item-7"}, {"id":"8","parent_id":"2","name":"Item-8"}, {"id":"9","parent_id":"2","name":"Item-9"}, {"id":"10","parent_id":"1","name":"Item-3"}, {"id":"11","parent_id":"10","name":"Item-10"},

您可能已经注意到每个 object 通过 parent_id 与他的父亲联系,parent_id 与他的 parent 的 ID 相关联。

我尝试创建一个自定义指令来读取响应并通过递归构建树结构。

到目前为止我只成功创建了树的第一层。 Demo

app.directive('tree',function(){
    var treeStructure = {
        restrict: "E",
        transclude: true,
        root:{
            response : "=src",
            Parent : "=parent"
        },
        link: function(scope, element, attrs){
            var log = [];
            scope.recursion = "";
            angular.forEach(scope.response, function(value, key) {
                if(value.parent_id == scope.Parent){
                    this.push(value);
                }
            }, log);
            scope.filteredItems = log;

            scope.getLength = function (id){
                var test = [];
                angular.forEach(scope.response, function(value, key) {
                    if(value.parent_id == id){
                        this.push(value);
                    }
                }, test);
                if(test.length > 0){
                    scope.recursion = '<tree src="scope.response" parent="'+id+'"></tree>';
                }
                return scope.recursion;
            };
        },
        template:
            '<ul>'
                +'<li ng-repeat="item in filteredItems">'
                    +'{{item.name}}<br />'
                    +'{{getLength(item.id)}}'
                +'</li>'
            +'<ul>'
    };
    return treeStructure;
});

app.controller('jManajer', function($scope){
    $scope.information = {
        legend : "Angular controlled JSon response",
    };

    $scope.response = [
        {"id":"1","parent_id":null,"name":"Item-0"},
        {"id":"2","parent_id":"1","name":"Item-1"},
        {"id":"3","parent_id":"2","name":"Item-3"},
        {"id":"4","parent_id":"2","name":"Item-4"},
        {"id":"5","parent_id":"2","name":"Item-5"},
        {"id":"6","parent_id":"2","name":"Item-6"},
        {"id":"7","parent_id":"2","name":"Item-7"},
        {"id":"8","parent_id":"2","name":"Item-8"},
        {"id":"9","parent_id":"2","name":"Item-9"},
        {"id":"10","parent_id":"1","name":"Item-2"},
        {"id":"11","parent_id":"10","name":"Item-10"},
    ];
});

有谁能告诉我如何通过递归将这种数组转换为树结构吗?

首先在嵌套数组中递归转换数组

var myApp = angular.module('myApp', []);

myApp.controller('jManajer', function($scope) {
  $scope.res = [];
  $scope.response = [{
    "id": "1",
    "parent_id": 0,
    "name": "Item-0"
  }, {
    "id": "2",
    "parent_id": "1",
    "name": "Item-1"
  }, {
    "id": "3",
    "parent_id": "2",
    "name": "Item-3"
  }, {
    "id": "4",
    "parent_id": "2",
    "name": "Item-4"
  }, {
    "id": "5",
    "parent_id": "2",
    "name": "Item-5"
  }, {
    "id": "6",
    "parent_id": "2",
    "name": "Item-6"
  }, {
    "id": "7",
    "parent_id": "2",
    "name": "Item-7"
  }, {
    "id": "8",
    "parent_id": "2",
    "name": "Item-8"
  }, {
    "id": "9",
    "parent_id": "2",
    "name": "Item-9"
  }, {
    "id": "10",
    "parent_id": "1",
    "name": "Item-2"
  }, {
    "id": "11",
    "parent_id": "10",
    "name": "Item-10"
  }, ];

  function getNestedChildren(arr, parent) {
    var out = []
    for (var i in arr) {
      if (arr[i].parent_id == parent) {
        var children = getNestedChildren(arr, arr[i].id)

        if (children.length) {
          arr[i].children = children
        }
        out.push(arr[i])
      }
    }
    return out
  }
  $scope.res = getNestedChildren($scope.response, "0");

  console.log($scope.res);
  $scope.nested_array_stingified = JSON.stringify($scope.res);

});
<!DOCTYPE html>
<html>

<head>
  <script src="https://code.angularjs.org/1.3.11/angular.js"></script>

</head>

<body ng-app="myApp" ng-controller="jManajer">

  {{nested_array_stingified}}
</body>

</html>

之后您可以按照此处的教程进行操作 http://sporto.github.io/blog/2013/06/24/nested-recursive-directives-in-angular/

在将数据传递到您的视图之前,您需要展开数据。 我稍微修改了你的代码,我也转换了你的数据并将深度和关系字段替换为整数,比较整数比比较字符串和空值更容易。

在这个 example 中,我使用了 Undescore.js 强大的功能来展开数组。

代码可以作为指令中的辅助函数找到:

unflatten = function (array, parent, tree) {

    tree = typeof tree !== 'undefined' ? tree : [];
    parent = typeof parent !== 'undefined' ? parent : {
        id: "0"
    };

    var children = _.filter(array, function (child) {
        return child.parent_id == parent.id;
    });

    if (!_.isEmpty(children)) {
        if (parent.id == "0" || parent.id == null) {
            tree = children;
        } else {
            parent['children'] = children
        }
        _.each(children, function (child) {
            unflatten(array, child)
        });
    }
    console.log(tree)
    return tree;
}

如果您想要 VanillaJs 解决方案,请查看此 piece of code

这里还有一个 demo 用您的数据模拟交互式树

下划线unflatten函数被采用from here .