Angularjs ng-repeat on two levels but only one output

I have a large object that looks something like this:

scope.marketplaces = {

    first_example : { ... },
    second_example : { ... },

    ...

};

      

What I am trying to do is loop through a large object like this:

<section>
    <ul>
        <li ng-repeat="(key, value) in marketplaces"></li>
    </ul>
</section>

      

And inside the loop, loop through each object, but instead of appending to the DOM, something like:

<li> ... first level loop ...

    <li> ... second level loop ... </li>
</li>

      

I would like to have only one <li></li>

, regardless of the level I am looking at. The reason I want it this way is because I need key

from the first loop to be referenced down and there is still only one li

.

I've read that I ng-repeat="friend in friends | filter:searchText"

can do what I want, but I'm not sure if in the filter expression I can dynamically specify key

or whatever is needed instead searchText

(I'm assuming this is an already known property of the object).

So my question is, can I achieve what I just explained with the help filter

, or is there another way to do this?

+3


source to share


1 answer


I hope I understood the question: would you like to have one ngRepeat per nested object. So kind of linearize an object.

The first approach is to create a filter:

app.filter('linear', function() {
  return function(value) {
    var result = {};
    for(var key in value) {
      for(var cKey in value[key]) {
        result[key+'_'+cKey] = value[key][cKey];
      }      
    }
    return result;
  };
});

      

and in thml:

<li ng-repeat="(key, value) in marketplaces | linear">
          {{key}}: {{value}}
</li>

      

But unfortunately AngularJS has problems when you create new elements in the filter. You may have a console-like error message:

10 $digest iterations reached

      



Without hacks, $$hash

you won't be able to achieve this functionality at the moment (please correct me if I'm wrong).

So I think the solution for now would be to observe the "markets" in the controller and create a new object using the same code as in the controller used in ngRepeat:

$scope.$watch('marketplaces', function(value) {
    var result = {};
    for(var key in value) {
      for(var cKey in value[key]) {
        result[key+'_'+cKey] = value[key][cKey];
      }      
    }
    $scope.linearMarketplaces = result;

  }, true);

      

And in HTML:

    <li ng-repeat="(key, value) in linearMarketplaces">
      {{key}}: {{value}}
    </li>

      

Plunker with both solutions: http://plnkr.co/edit/pYWFhqSqKAa9gpzek77P?p=preview

+4


source







All Articles