AngularJS orderby с массивом массивов и отдельными ключами

У меня есть табличные данные, которые я возвращаю с сервера в виде массива массивов данных и массива ключей, связанных с этими данными. Затем я хочу отсортировать по определенному ключу. Теперь я знаю, что могу предварительно обработать данные и объединить массив объектов, но я не хочу этого делать. Есть ли простой, встроенный способ сделать это?

Некоторый код, который на самом деле не сортирует, но отображает данные. CodePen.

JS:

var app = angular.module('helloworld', []);

app.controller('TestController', function() {
  this.headers = ['foo', 'bar'];
  this.data = [
    [ 'lol', 'wut' ],
    [ '123', 'abc' ]
  ];

  this.predicate = '';
});

HTML:

<table ng-app="helloworld" ng-controller="TestController as test">
  <thead>
    <tr>
      <th ng-repeat="heading in test.headers" ng-click="test.predicate = heading">{{ heading }}</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Predicate:</td>
      <td>{{ test.predicate }}</td>
    </tr>
    <tr ng-repeat="row in test.data | orderBy: test.predicate">
      <td ng-repeat="column in row">{{ column }}</td>
    </tr>
  </tbody>
</table>

2 ответа

Решение

Вы можете сделать это, но я бы предложил, чтобы ваш сервер возвращал вам данные в виде списка объектов json.

Чтобы отсортировать многомерный массив, вы в основном сортируете по индексу внутреннего массива. Ваш предикат будет содержать индекс столбца, по которому вы хотите отсортировать (0 или 1 в вашем случае)

<th ng-repeat="heading in test.headers" 
    ng-click="test.predicate = $index">
            {{ heading }}
</th>

Создайте функцию сортировки в вашем контроллере, как показано ниже:

 this.sorter = function(item){
    return item[test.predicate];
  }

Примените этот сортировщик в качестве выражения orderBy, как показано ниже:

<tr ng-repeat="row in data | orderBy: test.sorter">

Я разбудил и обновил ваш CodePen для вас: http://codepen.io/anon/pen/qvcKD

Для справки, решение, где массив упакован вместе со стандартным JS:

var app = angular.module('helloworld', []);

app.controller('TestController', function() {
  this.headers = ['foo', 'bar'];
  var data = [
    [ 'lol', 'abc' ],
    [ '123', 'wut' ]
  ];

  this.data = [];

  for (var i = 0, n = data.length; i < n; i++) {
    this.data.push({});
    for (var j = 0, m = this.headers.length; j < m; j++) {
      this.data[i][this.headers[j]] = data[i][j];
    }
  }

  this.predicate = '';
});

Или вместо этого с LoDash, как предложено @Antiga:

_.each(data, function(item) {
  this.data.push(_.zipObject(this.headers, item));
}, this);
Другие вопросы по тегам