0

I have a JSON object with different names for each property, like so:

var definitions = {
  foo: {
    bar: {abc: '123'},
    baz: 'def'
  },
  qux: {
    broom: 'mop',
    earth: {
      tree: 'leaf',
      water: 'fish'
    },
    fig: {
      qwerty: 'olive'
    }
  },
  blix: {
    worm: 'dirt',
    building: 'street'
  }
  ... more nested objects
};

Right now, I am displaying this data like so:

<div class="type" ng-repeat="(key,val) in definitions">
  <h4 ng-model="collapsed" ng-click="collapsed=!collapsed">{{key}}</h4>
  <div ng-show="collapsed">{{val}}</div>
</div>

And here's my controller:

App.controller('DefinitionsCtrl', function ($scope) {
  $scope.definitions = definitions;
});

{{val}} simply shows a condensed string of the property when its respective {{key}} is clicked. I would like to properly parse the val portion further, so for instance foo's nested properties (bar and baz) would have their own divs respectively. However, I would like to do this for all the nested values. Doing this manually is not an option (it's a huge file).

Is this possible considering all the nested names are different? Would I have to create a custom filter, or is this something I should handle in the controller?

1
  • I don't think the ng-model on an H4 tag even does anything. The ng-click just sets collapsed on each ng-repeat item scope, creating it the first time. Commented Oct 16, 2013 at 21:52

1 Answer 1

2

So if I understand correctly, you want a recursive ng-repeat? Your best bet is to create a custom directive.

Check out this sample directive that's recursive:

.directive('collection', function () {
return {
    restrict: "E",
    replace: true,
    scope: {
        collection: '='
    },
    template: "<ul><member ng-repeat='member in collection' member='member'></member></ul>"
}
})

.directive('member', function ($compile) {
return {
    restrict: "E",
    replace: true,
    scope: {
        member: '='
    },
    template: "<li>{{member.name}}</li>",
    link: function (scope, element, attrs) {
        // this is just un-compiled HTML, in the next step we'll compile it
        var collectionSt = '<collection collection="member.children"></collection>';
        if (angular.isArray(scope.member.children)) {       
            //compile and append another instance of collection
            $compile(collectionSt)(scope, function(cloned, scope)   {
                element.append(cloned); 
              });
        }
    }
}
})

See it running here: http://jsbin.com/acibiv/4/edit and a blog post about it: http://sporto.github.io/blog/2013/06/24/nested-recursive-directives-in-angular/ but don't follow the code in the blog post, it's incorrect. He didn't do the compile correctly.

Of course this will require a lot of customization by you. Instead of checking for "children' you must check to see if your value is an object.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you! This previous question was also helpful.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.