Troubleshooting problem with Angular's ng-repeat directive in dealing with varying number of child objects

I am currently dealing with tree-structured data where the parent nodes can have an indefinite number of children, and those children can also have an indefinite number of children, creating a deeply nested structure. While I have successfully formatted the data in JSON to reflect this nested structure, I am facing a challenge when it comes to building my Angular template. How can I effectively handle this level of indeterminacy?

Below is my initial attempt:

<div ng-repeat="object in manhole.data">

  <div ng-if="object.object"
       ng-repeat="childObject in object.object">

    <div ng-if="childObject.object"
         ng-repeat="childChildObject in childObject.object"></div>

  </div>

</div>

However, I have realized that this solution only works for a tree structure with a maximum depth of 2.

Answer №1

It's impossible to achieve this using only ng-repeat.

Your best bet is to incorporate a directive that automatically nests itself if it encounters a new child element.

I once created a custom directive for generating menus with an unknown number of sublevels. You can check it out here: http://plnkr.co/edit/8JL0Op?p=preview
Although I believe there may be more efficient ways to accomplish this (I developed this during my Angular learning phase), you might find some inspiration from this implementation.

Here's the code snippet:

angular.module('app', [])
.controller('Controller', ['$scope', '$timeout', function($scope, $timeout) {
 $scope.name = "Test";
 $scope.values = [
   {"name":"test1"},
   {"name":"test2", children:[
     {"name":"test21"}, 
     {"name":"test22"}, 
     {"name":"test23", children:[
     {"name":"test231"}, 
     {"name":"test232"}, 
     {"name":"test233"}
   ]}
   ]},
   {"name":"test3"},
   ];
}]);

angular.module('app').directive('hyMenu', function($compile) {
  return {
    restrict: 'A',
    scope:{
        menuList:"=hyMenu"
    },
    link: function(scope, element, attrs) {},
    templateUrl: function(element ,attrs) {
        if(attrs.sub=="true"){
            return 'hy-sub.htm';
        } else {
            return 'hy-menu.htm';
        }
    }
  };
}).directive('hyElement', function($compile) {
  return {
    restrict: 'A',
    scope: true,
    link: function(scope, element, attrs, menuCtrl) {
      if(!scope.elem.children){
                scope.elem.children=[];
        }
        if (scope.elem.children.length > 0){
          console.log(scope.elem.children); 
            element.append("<ul hy-menu='elem.children' data-sub='true'></ul>");
            $compile(element.contents())(scope);
        }
    },
    templateUrl:  function(element, attrs) {
        return 'hy-elem.htm';
    }
  };
});

Template files:

index.htm

<div class="hy-menu" hy-menu="values"></div>

hy-menu.htm

<ul>
    <li ng-repeat="elem in menuList" hy-element="elem"></li>
</ul>

hy-sub.htm

<li ng-repeat="elem in menuList" hy-element="elem"></li>

hy-elem.htm

{{elem.name}}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Do not directly change a prop - VueJS Datatable

Just starting out on Vue JS and encountered an issue while trying to create a Data Table by passing parent props to child components. An Error Occurred: [Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent ...

Altering the input type of a cloned element in Internet Explorer results in the loss of the value

When I have checkbox inputs displayed in a modal with preset value attributes, upon clicking "OK", I clone them and change their input types to hidden, then append them to a div in the document body. However, when trying to retrieve their values using jQue ...

Trouble with Angular localization module displaying codes instead of non-ASCII characters

I am currently utilizing a module from this source to facilitate localization efforts. However, I have encountered an issue where special characters are being displayed as their corresponding ASCII codes instead of their actual symbols. For example, &a ...

What is the process for reversing the texture application direction on a CylinderGeometry object?

Is it possible to reverse the orientation of texture mapping on a CylinderGeometry object? var obj = new THREE.Mesh( new THREE.CylinderGeometry(20, 15, 1, 20), new THREE.MeshLambertMaterial({color: 0x000000}) //the material is later changed to the ...

Tips for Creating an Animated Progress Bar in a Slider

After implementing jQuery, I managed to create a unique slider on my website. This slider included a thumbnail with captions for each photo. Positioned below the thumbnail was a progress bar fixed in the center between the caption and the image. Users can ...

AngularJS makes it easy to push parameters to a URL in order to

I'm currently working on an AngularJS app where I need to dynamically push the user's company name to the URL. For example, it should look like www.myapp.com/samsung or www.myapp.com/toyota. My approach to achieve this is to first retrieve the u ...

What is the proper method for running a script using the Selenium JavascriptExecutor?

On my test.html page, I've included the following code snippet: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html> <head> </head> <body> ...

Is there a way to directly update the value of a nested object array using v-model in VUE?

Looking to update a value in JSON using v-model { class: "data.child", "myform.input1": [true, "<input1 value>"] } <input type="text" v-model="<what should be inserted here?>" > //update the value directly in my ...

The results from various <div> elements are displayed based on the selection made from the dropdown menu

<body> <label for="country">Country : </label> <select id="country"> <option>Please select</option> <option name="CountryRevenue">Revenue</option> <option name="CountryQuantity">Quantity ...

Deleting the previous ion-view from DOM in Ionic v1 with Angular

I have been working on modifying an app built in Ionic v1. Within the app, there is a primary View titled 'Client's Profile' that contains links to two other Views: Support Request and Complaints. In the Support Request view, there is a Te ...

What is the process of integrating an ejs view engine with express on Netlify?

Need help configuring the ejs view engine with netlify I attempted to set app.set('view engine', 'ejs'), but didn't see any results. const express = require('express'); const path = require('path'); const serv ...

Tips for concealing a container in angularJS when all entries have been filtered

In my AngularJS 1.4.3 application, I have implemented a filter feature. My goal is to hide the div container if all entries in vm.nightServices are filtered out. Even though I tried using ng-show="vm.nightServices.length > 0", it did not work as expecte ...

What is the best method for integrating opensea-js using a script tag in a vanilla HTML/JS environment?

Is there a way to incorporate opensea-js into an html/js project that does not rely on node.js? The source code for opensea-js is only available on github and npm at https://github.com/ProjectOpenSea/opensea-js I came across this link: However, when I tr ...

When testing on jsfiddle, the script functions properly with pure JavaScript. However, when integrating it into my own code, it fails to work unless jQuery is included

Visit this link to access the code snippet. Below is my code: const chk = document.getElementById('chk'); const body = document.body; $(function(){ chk.addEventListener('change', () => { $('.body').toggleClass( ...

Preventing Button Click with JQuery Tooltip

I've implemented a JQuery tooltip plugin on my website and it's working great. However, I'm facing an issue where I cannot click on the input button that appears when hovering over the tooltip. It seems like the button is not truly part of t ...

I must display the output in the proper format as illustrated below

angular.forEach(caseChangeRecord, function(change, key) { if (caseChangeRecord != 'undefined') { body += change.fieldName + ' : ' + change.newValue; } }); Expected Display Output: A:B A:B A:B ...

Does AngularJS come with caching enabled by default?

Delving into the world of angularjs, I recently came across this documentation that suggested adding a specific option to the $http service configuration in order to utilize cache: $http({ method : "GET", url : "somehost/somepath", cache : tru ...

Update class name in React component based on state change

My current setup involves the setting of active and class flags as shown below: constructor(props) { super(props); this.state = {'active': false, 'class': 'album'}; } handleClick(id) { if(this.state.active){ this.s ...

Using a string as a key for an object's property

function createObject(argName, argProperties){ var object = {}; object[argName] = argProperties; } I am calling my function in the following manner. createObject('name', objectProperties); The issue I am encountering is w ...

Is there a way to troubleshoot a webpack-compiled npm module effectively?

Looking to debug an npm module compiled with webpack by setting breakpoints and stepping through the code? The issue may arise when importing the module locally using npm link, as only the compiled code is accessible for debugging from the application. W ...