5

Let's say we have an array of people in the JSON format. Each entity has about 100 attributes. The standard approach of using ng-repeat:

...
<tr>
  <th>Attribute1</th>
  <th>Attribute2</th>
  ...
  <th>AttributeN</th>
</tr>
...
<tr ng-repeat="obj in jsonArray">
  <td>{{ obj.attr1 }}</td>
  <td>{{ obj.attr1 }}</td>
  ...
  <td>{{ obj.attrN }}</td>
</tr>

Which produces the following table:

Attribute1 | Attribute2 | ... | AttributeN
------------------------------------------
value1.1   | value1.2   | ... | value1.N
value2.1   | value2.2   | ... | value2.N
...
valueN.1   | valueN.2   | ... | valueN.N

Instead of this, I need:

Attribute1 | value1.1 | value2.1 | ... | valueN.1
Attribute2 | value1.2 | value2.2 | ... | valueN.2
...        | ...      | ...      | ... | ...
AttributeN | value1.N | value2.N | ... | valueN.N

So the question: how do I achieve this?

  • Without manipulation "by hands" (js-jQuery), without leaving angular world - there will be some event handlers & etc.
chip
  • 65
  • 1
  • 8

3 Answers3

5

If I understand correctly what you are trying to achieve, then this is how you would do it:

<table>
  <tr ng-repeat="(key, value) in people[0]">
    <th>{{key}}</th>
    <td ng-repeat="person in people">
      {{person[key]}}
    </td>
  </tr>
</table>

Assuming your data is an array of objects with the same properties, you iterate over the first object in the array to get the keys, which would make the vertical table headers.

After that, you iterate over the whole array and simply output the value for the specific key. Here's a fiddle showing the output:

http://jsfiddle.net/andreiho/huL8pvmg/1/

Of course, you'd have to change things around if you want to manually define the names of your headers. This example just takes the keys in your data. You could also manipulate the data before sending it to the view, so you only send the keys you need.

andreiho
  • 336
  • 1
  • 6
  • you are my hero! u make my day - just simple =) Good job! – chip Dec 16 '15 at 10:27
  • but there is one problem - too much repeaters. I mean: 10 objects with 100 attrs... this view is only one tab in compicated page... – chip Dec 16 '15 at 10:35
  • Did you try it out and it performs slowly? Or are you generally worried about using too many repeaters? I guess in cases like this it's quite difficult to keep it to a minimum. I don't see any other way you could achieve this without actually writing a custom filter to manipulate your data. And at the end of the day, you'll have to run some sort of loop in the filter anyway. – andreiho Dec 16 '15 at 11:17
  • I'm completely agree - it will be loop anyway and seems there is no better solution. And yours variant (without using filter) more clean & faster... Just done with my real world example - there is no performance issues.Thanks a lot! – chip Dec 16 '15 at 11:42
2

One approach to solve this problem is by restructuring the jsonArray into an indexed object data structure.

DEMO

Javascript

.controller('DemoController', function(Data, $scope) {

  Data.all().then(function(response) {
    $scope.indexedObjects = indexByAttribute(response.data);
  });

  function indexByAttribute(collection) {
    return collection.reduce(function(result, item) {

      angular.forEach(item, function(value, index) {
        result[index] = result[index] || [];
        result[index].push(value);
      });

      return result;
    }, {});
  }

});

HTML

<table>
  <tr ng-repeat="(index, values) in indexedObjects track by index">
    <th>{{ index }}</th>
    <td ng-repeat="value in values track by $index">
      {{ value }}
    </td>
  </tr>
</table>
ryeballar
  • 29,658
  • 10
  • 65
  • 74
1

You could write custom filter.

yourModule.filter('myFilter', [ function (arr) {
    var newArr = [];
    // loop over arr and construct newArr as you wish
    ... 

    return newArray;
} ])

Use it like`

<tr ng-repeat="obj in (jsonArray | myFilter)">
    <td>{{ obj.attr1 }}</td>
    <td>{{ obj.attr2 }}</td>
    ...
    <td>{{ obj.attrN }}</td>
</tr>

This way ng-repeat will convert your jsonArray to new formed array and use it in the loop, but you will still have your jsonArray untouched in case you use it in other places.

Artur Aleksanyan
  • 480
  • 5
  • 10
  • I think - there is nothing to do here with the filter. It's all about data representation structrure. – chip Dec 16 '15 at 10:00
  • after some thought... maybe you're right & it's the best way =) I will check it out. Thks! I'll be back – chip Dec 16 '15 at 10:17
  • I think the above solutions are more suitable for me – chip Dec 16 '15 at 11:10