Monojit Sarkar
Monojit Sarkar

Reputation: 2451

AngularJS: How to develop master with nested details using ng-repeat

i have read this post https://stackoverflow.com/a/18295177/6188148 but my json looks bit different. here is my json.

[{"ID":1,"Name":"Suzy","ParentID":0},
{"ID":2,"Name":"Somi","ParentID":1},
{"ID":3,"Name":"Romi","ParentID":2},
{"ID":4,"Name":"Jumi","ParentID":3},
{"ID":5,"Name":"Gargi","ParentID":0},
{"ID":6,"Name":"Sujoy","ParentID":5},
{"ID":7,"Name":"Kamal","ParentID":6},
{"ID":8,"Name":"Joy","ParentID":0},
{"ID":9,"Name":"Sumana","ParentID":8},
{"ID":10,"Name":"Alex","ParentID":0}]

in my case relation establish with ID and ParentID. the relation can be nested upto nth level. so tell me how to use ng-repeat to show parent and child data.

this way i tried

<div ng-app="myApp">
    <ul class="nav nav-pills" data-ng-controller= "MasterDetails" >
        <li
            data-ng-repeat="parent in details | filter: { ParentID: 0 }" >
            <a href="#/customers"> {{ parent.Name }} </a>
            <ul>
                <li data-ng-repeat="child in details | filter: { ParentID: parent.ID }">
                    {{ child.Name }}
                </li>
            </ul>
        </li>
    </ul>
</div>

angular.module("myApp", []).
controller("MasterDetails", ['$scope', function($scope) {
    $scope.details = [{"ID":1,"Name":"Suzy","ParentID":0},
{"ID":2,"Name":"Somi","ParentID":1},
{"ID":3,"Name":"Romi","ParentID":2},
{"ID":4,"Name":"Jumi","ParentID":3},
{"ID":5,"Name":"Gargi","ParentID":0},
{"ID":6,"Name":"Sujoy","ParentID":5},
{"ID":7,"Name":"Kamal","ParentID":6},
{"ID":8,"Name":"Joy","ParentID":0},
{"ID":9,"Name":"Sumana","ParentID":8},
{"ID":10,"Name":"Alex","ParentID":0}];
}]);

here is jsfiddle https://jsfiddle.net/tridip/s0svpaev/2/

the above code is working but not getting right output. hierarchy should be look like this way

Suzy
    Somi
        Romi
            Jumi
Gargi
    Sujoy
        Kamal
Joy
    Sumana
Alex    

where i made the mistake in code for which i am not getting right output. thanks

Upvotes: 2

Views: 519

Answers (2)

Yin Gang
Yin Gang

Reputation: 1443

Presume include jQuery and not care dom opt perfomance too much, This anwser can match your requirement.

angular.module('app', [])
  .controller('appCtrl', function($scope) {
    $scope.data = [{
      "ID": 1,
      "Name": "Suzy",
      "ParentID": 0
    }, {
      "ID": 2,
      "Name": "Somi",
      "ParentID": 1
    }, {
      "ID": 3,
      "Name": "Romi",
      "ParentID": 2
    }, {
      "ID": 4,
      "Name": "Jumi",
      "ParentID": 3
    }, {
      "ID": 5,
      "Name": "Gargi",
      "ParentID": 0
    }, {
      "ID": 6,
      "Name": "Sujoy",
      "ParentID": 5
    }, {
      "ID": 7,
      "Name": "Kamal",
      "ParentID": 6
    }, {
      "ID": 8,
      "Name": "Joy",
      "ParentID": 0
    }, {
      "ID": 9,
      "Name": "Sumana",
      "ParentID": 8
    }, {
      "ID": 10,
      "Name": "Alex",
      "ParentID": 0
    }];
  })
.directive('tree',function($filter){
  return {
    restrict:'EA',
    scope:{
      data:'='
    },
    link:function(scope,element,attrs){
      scope.data = $filter('orderBy')(scope.data,'ParentID');
      var html = $('<ul id="tree-outer-0"></ul>');
      element.append(html);
      angular.forEach(scope.data,function(val,index){
        var tree = $('<li id="tree-inner-'+val.ID+'">'+val.Name+'</li>');
        var parent = $('ul#tree-outer-'+val.ParentID);
        if(parent.length){
          parent.append(tree);
        }else{
          var parents = $('li#tree-inner-'+val.ParentID);
          var parent = $('<ul id="tree-outer-'+val.ParentID+'"></ul>');
          parent.appendTo(parents).append(tree);
        }
      });
    }
  }
});
<script src="//cdn.bootcss.com/angular.js/1.5.5/angular.min.js"></script>
<script src="//cdn.bootcss.com/jquery/2.1.4/jquery.js"></script>
<div ng-app="app" ng-controller="appCtrl">
  <tree data="data"></tree>
</div>

Upvotes: 1

Marwen Trabelsi
Marwen Trabelsi

Reputation: 4257

Based on your link, I created this plnkr with some modifications to fit your needs.

I just added the getSubPeople function in the controller to get a sub array that represent the elder parents and pass them immediately to the directive for sub rendering:

Our partial:

<ul>
    <li ng-repeat="p in peoples">
      {{p}}
      <div ng-switch on="p.ParentID > 0">
        <div ng-switch-when="true">
            <div ng-init="peoples = getSubPeople(p.ParentID);" ng-include="'partialPeoples.html'"></div>
        </div>
      </div>
    </li>
</ul>

Our Controller :

  var app = angular.module('angularjs-starter', []);
    app.controller('MainCtrl', function($scope, $http) {

        $scope.peoples = [{"ID":1,"Name":"Suzy","ParentID":0},
                          {"ID":2,"Name":"Somi","ParentID":1},
                          {"ID":3,"Name":"Romi","ParentID":2},
                          {"ID":4,"Name":"Jumi","ParentID":3},
                          {"ID":5,"Name":"Gargi","ParentID":0},
                          {"ID":6,"Name":"Sujoy","ParentID":5},
                          {"ID":7,"Name":"Kamal","ParentID":6},
                          {"ID":8,"Name":"Joy","ParentID":0},
                          {"ID":9,"Name":"Sumana","ParentID":8},
                          {"ID":10,"Name":"Alex","ParentID":0}];

       $scope.getSubPeople = function(parentId) {
       var arr = [];
       for(var i=parentId; i>0 ; i--){
           arr.push($scope.peoples[i-1]);
         }
         return arr;
       }

    });

Upvotes: 2

Related Questions