3

Is there a way to perform nested loops in an AngularJS view without creating hidden dummy elements?

Something like this:

<ul>
    <li ng-repeat="gem in activeHero.gems"
        ng-repeat="(key, value) in gem.attributes"
        ng-repeat="attr in value">
            {{attr.text}}
    </li>
</ul>

or this

<ul>
    <li ng-repeat-start="gem in activeHero.gems"
        ng-repeat-start="(key, value) in gem.attributes"
        ng-repeat="attr in value">
            {{attr.text}}
    </li ng-repeat-end 
         ng-repeat-end>
</ul>

Neither of these is possible AFAIK.

I basically want my HTML to have a different structure than the JSON it's based on. How could I achive this? Is there a way to create loops inside a view without an HTML element?

The examples above would loop over a JSON structure like this:

JSON (stripped out a lot for clarity)

"activeHero" = {
  "gems" : [ {
    "attributes" : {
      "primary" : [ {
        "text" : "+220 Intelligence"
      } ],
      "secondary" : [ ],
      "passive" : [ ]
    }
  }, {
    "attributes" : {
      "primary" : [ {
        "text" : "+220 Intelligence"
      } ],
      "secondary" : [ ],
      "passive" : [ ]
    }
  }, {
    "attributes" : {
      "primary" : [ {
        "text" : "+160 Intelligence"
      } ],
      "secondary" : [ ],
      "passive" : [ ]
    }
  } ]
}

(This is an actual JSON response from the Blizzard API for the video game "Diablo 3")

8
  • What do you mean by hidden dummy elements? Commented Jan 5, 2015 at 15:07
  • 5
    why don't you format your json via javascrip? Don't try with repeater. It would result in lack of performance. Commented Jan 5, 2015 at 15:07
  • @pixelbits He means creating elements to add ng-repeat to that don't actually show on the page Commented Jan 5, 2015 at 15:10
  • @pixelbits look at this guy: vanderwijk.info/blog/nesting-ng-repeat-start He uses additional HTML elements to perform the nested loops which is their only purpose. They're hidden via CSS. Dummy elements for looping (which is stupid IMO) Commented Jan 5, 2015 at 15:10
  • 1
    It is not possible without creating a custom directive or filter. Also There would be more listener more dirty checks etc. that may throw your app. Commented Jan 5, 2015 at 15:31

1 Answer 1

4

Try format your json before render;

$scope.formattedData = [];
angular.forEach(activeHero.gems, function(value, key){
      var item = {
         //set filed you want
      }
      angular.forEach(value.atrtibutes, function(value2, key2){
               item['propyouwant'] = value2[propyouwant]
               angular.forEach(value2.primary, function(value3, key3){
                      item['propyouwant'] = value3[propyouwant]
                     $scope.formattedData.push(angular.extend({}, item));
               })
      })
})

//now you can render your data without somersould

EDIT

For increasing performance and avoid to use angular extend;

$scope.formattedData = [];
angular.forEach(activeHero.gems, function(value, key){

      angular.forEach(value.atrtibutes, function(value2, key2){
               angular.forEach(value2.primary, function(value3, key3){
                     //start build your item here
                      var item = {
                        prop1: value['prop'],
                        prop2: value2['prop']
                       }
                     //not required extend item;
                     $scope.formattedData.push(item);
               })
      })
})
Sign up to request clarification or add additional context in comments.

Comments

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.