简体   繁体   中英

Getting values for a nested object with different names using ng-repeat

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?

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.

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