0

Considering I am unaware of how many sub objects my parent object will have how can I create a menu using ng-repeat or any other method.

Let's say my object is:

var Obj=[{
    "node1":[{
         "Subnode1":[{
                "SubSubNode1":[{
                       ...
                    }]
              }]
    },{
        "Subnode2":[{ ... }]
    }]
},{
    "node2":[{ ... }]
}];

How can i create a menu for the above object using angularJS?

Wasimakram Mulla
  • 511
  • 7
  • 24
  • 2
    What did you try so far? – Kursad Gulseven Jan 07 '16 at 06:15
  • I was thinking how or from where do I start with? is there any possible way to do the same in AngularJS? – Wasimakram Mulla Jan 07 '16 at 06:21
  • You may use nested 'ng-repeat's with bind-once (not necessary, for performance). If you cannot accomplish what you wish, people here will be helping you if you post your code. – Kursad Gulseven Jan 07 '16 at 06:27
  • I have added a plunker for your reference http://plnkr.co/edit/zAdS6qUoxQL5M0N2g6Ec?p=preview and @Aniket nodes can be unlimited in a tree structure. need a solution which can have ng-repeats dynamic or some other inbuild directive which can help me out for this. – Wasimakram Mulla Jan 07 '16 at 06:43
  • I found this link extremely efficient to do this ( http://stackoverflow.com/a/14460332/3214856 ). Just remove the delete functionality according to your need: – Aniket Sinha Jan 07 '16 at 09:17

3 Answers3

0

You need to know beforehand the depth of your subnodes.

Use nested ng-repeat to populate your menus. Here's something to get you started on nested ng-repeat:

JS: $scope.menu = obj; //pass your menu object to view

HTML:

            <div ng-repeat="m in menu">
                ...
                <div ng-repeat="s in m">
                   ...
                   <div ng-repeat="sn in s">
                     ...
                   </div>
                </div>
            </div>

Here's a fiddle from vojtajina doing exactly the same you want to achieve.

Aniket Sinha
  • 6,001
  • 6
  • 37
  • 50
0

You can use a recursive ng-repeat using an ng-include template which goes something like this:

<script type="text/ng-template" id="menu-node.html">
  <markup-of-your-node>{{ node.name }}</markup-of-your-node>
  <ul>
    <li ng-repeat="childNode in node.children" ng-include="'menu-node.html'">
    </li>
  </ul>
</script>

<ul>
  <li ng-repeat="node in menu.nodes" ng-include="'menu-node.html'"></li>
</ul>

To use this technique, you'll need to update your object to the following structure:

var nodes=[
  {
    "name": "node1",
    "children":[
      {
        "name": "Subnode1",
        "children":[
          {
            "name": "SubSubNode1",
            "children":[{ ... }]
          }
        ]
      },
      {
        "name": "Subnode2",
        "children":[{ ... }]
      }
    ]
  },
  {
    "name": "node2",
    "children":[{ ... }]
  }
];
cloudlena
  • 865
  • 11
  • 14
0

You may write a directive for menu item and use it recursively along your nodes. Recursive directives will cause "too much recursion" error; so, you will need to use RecursionHelper from this post.

See the updated Plunker.

.directive("menuNode", function(RecursionHelper){

   return {
        scope: {
            menuNode: '=',
        },
        template: '<ul><li ng-repeat="menuItem in menuNode track by $index">{{menuItem.label}}<div ng-if="menuItem.nodes" menu-node="menuItem.nodes"></div></li></ul>',
    compile: function(element) {
        // Use the compile function from the RecursionHelper,
        // And return the linking function(s) which it returns
        return RecursionHelper.compile(element);
    }
      };

})
Community
  • 1
  • 1
Kursad Gulseven
  • 1,978
  • 1
  • 24
  • 26