LBA
LBA

Reputation: 4089

Recursive Template with Concatenating Strings

I am fighting this since a while and as an Angular Noob this drives me crazy.

From my frontend I get a JSON like this:

{
  "LEVEL1": {
    "LEVEL21": {
      "LEVEL31": {
        "VALUE1": null,
        "LEVEL41": {
          "VALUE2": null,
          "VALUE3": null
        },
        "LEVEL42": {
          "VALUE4": null,
          "VALUE5": null
        }
      },
      "LEVEL32": {
        "VALUE6": null,
        "LEVEL51": {
          "VALUE7": null,
          "VALUE8": null
        }
      }
    },
    "LEVEL22": {
      "VALUE9": null,
      "VALUE10": null,
      "VALUE11": null
    }
  }
}

There is no specific order and I have no real figures to count/extract or something similar.

What I like to achieve is to display some kind of tree, so to display every entry (with some intent per 'level') with a + sign to open/display the next level per entry - but only when there is a next level (= value isn't null).

For every entry for which no next level is existing I need to have some 'click' functionality which gives me a concatenated string of the full path, so e.g. something like:

"LEVEL1.LEVEL21.LEVEL42.VALUE5"

So far I tried to resolve this by ng-repeats but as I don't know the depth of the structure I can't hardcode it (and it's superugly as well).

Next thing I tried is some template directive but here I am lost in keeping the scope to have my full string in the end.

Does someone have some inspiration for me?

Upvotes: 1

Views: 34

Answers (1)

Michael G
Michael G

Reputation: 6745

You can build a recursive ng-repeat like so:

  <script type="text/ng-template" id="tree_item_renderer.html">

    {{ key }}

    <ul ng-class="{collapse: collapsed, clicky: data !== null}">
      <li ng-repeat="(key, data) in data" 
          ng-include="'tree_item_renderer.html'" 
          ng-init="path = path + (path !== undefined ? '.' : '') + key"
          ng-click="setPath(path); collapsed = !collapsed; $event.stopPropagation();">

      </li>
    </ul>

  </script>

  <li ng-repeat="(key, data) in menuData" 
      ng-include="'tree_item_renderer.html'" 
      ng-click="collapsed = !collapsed; $event.stopPropagation();"></li>

Controller:

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

app.controller('MainCtrl', function($scope) {

  $scope.setPath = function(path) {
    alert(path);
  };

  $scope.menuData = {
    "LEVEL1": {
      "LEVEL21": {
        "LEVEL31": {
          "VALUE1": null,
          "LEVEL41": {
            "VALUE2": null,
            "VALUE3": null
          },
          "LEVEL42": {
            "VALUE4": null,
            "VALUE5": null
          }
        },
        "LEVEL32": {
          "VALUE6": null,
          "LEVEL51": {
            "VALUE7": null,
            "VALUE8": null
          }
        }
      },
      "LEVEL22": {
        "VALUE9": null,
        "VALUE10": null,
        "VALUE11": null
      }
    }
  };
});

Here is a working plunker example.

Upvotes: 1

Related Questions