2015-02-12 6 views
8

Я использую groupBy от angular-filter для группировки массива объектов по их дате.Angularjs groupBy + orderBy

<div ng-repeat="(day, dayEvents) in events | groupBy: 'date')"> 
<h3>{{ day | date: mediumDate }}</h3> 
</div> 

Который производит следующее:

Feb 9, 2015 
Feb 10, 2015 
Feb 11, 2015 
Feb 12, 2015 

Как я могу изменить порядок, чтобы начать с самого последнего момента? При печати на консоли массив печатается с заказом я хочу:

Object { 
    1423699200000: Array[1], 
    1423612800000: Array[7], 
    1423526400000: Array[11], 
    1423440000000: Array[1] 
} 

Я также написал пользовательский фильтр, чтобы изменить порядок после GroupBy:

.filter("reverseOrder", function() { 
     function sortNumber(a,b) { 
      return parseInt(b) - parseInt(a); 
     } 
     return function(collection) { 
      var keys = Object.keys(collection).sort(sortNumber); 
      var reveredCollection= {}; 
      var length=collection.length; 
      angular.forEach(keys, function(key) { 
       reveredCollection[key] = collection[key]; 
      }); 
      return reveredCollection; 
     } 
    }) 

который я применил, как это:

<div ng-repeat="(day, dayEvents) in events | groupBy: 'date' | reverseOrder)"> 
    <h3>{{ day | date: mediumDate }}</h3> 
</div> 

ответ

18

Недавно была та же проблема. groupBy создает объект, но orderBy нуждается в массиве, поэтому есть немного фанки. Я закончил тем, что получил ответ прямо со своей страницы проблем, где один из авторов отлично справляется с объяснением этого в комплекте с образцами кода, которые были в основном для копирования/вставки для меня.

https://github.com/a8m/angular-filter/issues/57#issuecomment-65041792

-1

Простой способ обратить массив является использование кода из this answer

app.filter('reverseOrder', function() { 
    return function(items) { 
    return items.slice().reverse(); 
    }; 
}); 

<div ng-repeat="(day, dayEvents) in events | groupBy: 'date' | reverseOrder)"> 
    <h3>{{ day | date: mediumDate }}</h3> 
</div> 
+0

По-прежнему, похоже, что фильтр возврата не оказывает никакого влияния на отображение элементов. – Shakur

-2

попытка использования -

<div ng-repeat="(day, dayEvents) in events | groupBy: '-date' "> 

P.S- Я не использовал GroupBy до сих пор никуда Но этот минус вещь хорошо работает с атрибутом OrderBy!

+0

groupBy и отрицательный знак не связаны. У них нет никаких отношений –

0

Мы можем добиться этого путем упорядочения данных в контроллере & превращающего выход GroupBy к массиву.

В контроллере, порядок записи перед отправкой его для просмотра:

$scope.events = $filter('orderBy')(events, '-date'); 

Теперь шаблон, получает данные в отсортированном порядке. После группировки, мы должны преобразовать его в массив:

<div ng-repeat="(day, dayEvents) in events | groupBy: 'date' | toArray:true)"> 
    <h3>{{ day | dayEvents[0].date: mediumDate }}</h3> 
</div> 
2

Оказывается метод собственно является использование | toArray: true | orderBy: customMappingFunction, однако, я обнаружил, что производительность это будет ужасно. Я придумал решение, которое сохраняет производительность до и производит правильный результат - (! Хотя это кажется немного странным)

<div ng-repeat="(key, results) in allResults | groupBy: '-someKey')"> 
    <h3>{{ key | ltrim: '-' }}</h3> 
    <ul> 
     <li ng-repeat="result in results"> 
      {{ result }} 
     </li> 
    </ul> 
</div> 

По какой-то причине, добавив - ли заставить groupBy правильно сортировать, но он также добавляет его в key, поэтому мы можем просто удалить его!