AngularJS - Json到Tree结构

时间:2015-01-30 14:31:50

标签: javascript arrays json angularjs recursion

我已经看到很多答案将Json响应变成了Ul Tree结构。 问题是所有这些主题围绕嵌套响应指向 out父对象和子对象之间的关系。

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

以下是回复的一部分:

  

{" ID":" 1"" PARENT_ID":空,"名称":"项目-0&# 34;},   {" ID":" 2"" PARENT_ID":" 1""名称":"项-1"},   {" ID":" 3"" PARENT_ID":" 2""名称":"项-2"},   {" ID":" 4"" PARENT_ID":" 2""名称":"项-4"},   {" ID":" 5"" PARENT_ID":" 2""名称":"项-5"},   {" ID":" 6"" PARENT_ID":" 2""名称":"项-6"},   {" ID":" 7"" PARENT_ID":" 2""名称":"项-7"},   {" ID":" 8"" PARENT_ID":" 2""名称":"项-8"},   {" ID":" 9"" PARENT_ID":" 2""名称":"项-9"},   {" ID":" 10"" PARENT_ID":" 1""名称":"项-3"},   {" ID":" 11"" PARENT_ID":" 10""名称":"项-10"},

你可能已经注意到每个对象通过parent_id与他父亲联系,而parent_id被连接到他父母的id。

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

直到现在我才成功创建树的第一级。 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"},
    ];
});

有没有人可以告诉我如何通过递归将这种数组转换为Tree结构?

2 个答案:

答案 0 :(得分:2)

首先在嵌套的

中递归转换数组

&#13;
&#13;
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);

});
&#13;
<!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>
&#13;
&#13;
&#13;

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

答案 1 :(得分:1)

您需要先将数据展开,然后再将其传递到视图中。 我稍微修改了你的代码,我也改变了你的数据并用整数替换了深度和关系字段,比较整数而不是比较字符串和空值更容易。

在这个example我使用过Undescore.js&#39;强大的功能,以使阵列松散。

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

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模拟带有数据的交互式树

下划线取消功能from here