简体   繁体   中英

How do I recursively iterate over an object that has unknown hierarchies with Angular JS?

So take this example:

http://jsfiddle.net/7U5Pt/

Here I've got an object that describes a (very basic) menu. Each item can have multiple children with potentially unlimited levels of hierarchy. The ng-repeat directives I'm using to turn it into <ul><li> elements work fine for the first two levels, but not for the third or any subsequent level of the hierarchy.

What's the best way to recursively iterate over this object, dealing with unlimited levels of children?

Any help much appreciated!

Here's the code incase the fiddle goes away:

HTML:

<div ng-app="myApp">
<div ng-controller="myCtrl">
    <nav class="nav-left">
        <ul ng-repeat="item in mytree.items">
            <li>NAME: {{ item.name }}
                <ul ng-repeat="item in item.children.items">
                    <li>SUB NAME: {{ item.name }}</li>
                </ul>
            </li>
        </ul>
    </nav>
</div>

JS:

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

myApp.controller('myCtrl', function ($scope) {
  $scope.mytree = {
  "items": [{
    "name": "one",
    "children": {
      "items": [
        {
          "name": "one sub a",
          "children": {
            "items": [{
              "name": "one sub level two a"
            },
            {
              "name": "one sub level two b"
            }]
          }
        },
        {
          "name": "one sub b"
        }
      ]
    }
  },
  {
    "name": "two"
  },
  {
    "name": "three"
  },
  {
    "name": "four",
    "children": {
      "items": [{
        "name": "four sub a"
      },
      {
        "name": "four sub b"
      }]
    }
  },
  {
    "name": "five"
  }]
};
});

So it turns out that the best way to do this, for anyone interested, is with the angular-recursion helper here:

https://github.com/marklagendijk/angular-recursion

This allows you to call the ng-repeat function recursively. So in your view, something like:

<tree family="mytree"></tree>

and then define a directive for that calls itself like so:

.directive('tree', function(RecursionHelper) {
  return {
    restrict: "E",
    scope: {family: '='},
    template: 
      '{{ family.name }}'+
      '<ul ng-if="family.children">' + 
      '<li ng-repeat="child in family.children">' + 
      '<tree family="child"></tree>' +
      '</li>' +
      '</ul>',
    compile: function(element) {
      return RecursionHelper.compile(element);
   }
 };
});

Apparently the recursion helper is necessary to stop some sort of infinite loop thing, as discussed here . Thanks to @arturgrzesiak for the link!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM