【问题标题】:AngularJS - Json to Tree structureAngularJS - Json 到树结构
【发布时间】:2015-03-30 01:23:46
【问题描述】:

我已经看到很多将 Json 响应转换为 Ul 树结构的答案。 问题是所有这些主题都围绕着一个嵌套响应指向 搞清楚父对象和子对象的关系。

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

以下是部分回复:

{"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"},

你可能已经注意到,每个对象通过 parent_id 连接到他的父亲,而 parent_id 连接到他父母的 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"},
    ];
});

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

【问题讨论】:

    标签: javascript arrays json angularjs recursion


    【解决方案1】:

    在将数据传递到视图之前,您需要对其进行展平。 我对您的代码进行了一些修改,还对您的数据进行了转换,并用整数替换了深度和关系字段,比较整数比比较字符串和空值更容易。

    在这个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 用您的数据模拟交互式树

    下划线未展平功能取自from here

    【讨论】:

      【解决方案2】:

      在嵌套的第一个递归中转换你的数组

      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/

      【讨论】:

        猜你喜欢
        • 2012-10-23
        • 1970-01-01
        • 1970-01-01
        • 2019-08-20
        • 1970-01-01
        • 1970-01-01
        • 2017-06-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多