Angularjs groupBy + orderBy
Angularjs groupBy + orderBy
我正在使用 angular-filter 中的 groupBy 按日期 属性.
对一组对象进行分组
<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>
反转数组的更简单方法是使用 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>
尝试使用 -
<div ng-repeat="(day, dayEvents) in events | groupBy: '-date' ">
P.S- 直到现在我还没有在任何地方使用过 groupBy!但是这个减去的东西与 orderBy 属性配合得很好!
最近遇到了同样的问题。 groupBy
创建了一个对象,但是 orderBy
需要一个数组,所以这里有点古怪。我最终直接从他们的问题页面得到了答案,其中一位作者很好地解释了它,并提供了对我来说基本上 copy/paste 的代码示例。
https://github.com/a8m/angular-filter/issues/57#issuecomment-65041792
我们可以通过在控制器中对数据进行排序并将 groupBy 输出转换为数组来实现这一点。
在控制器中,在将记录发送到视图之前对其进行排序:
$scope.events = $filter('orderBy')(events, '-date');
现在是模板,按排序顺序接收数据。分组后,我们需要将其转换为 Array :
<div ng-repeat="(day, dayEvents) in events | groupBy: 'date' | toArray:true )">
<h3>{{ day | dayEvents[0].date: mediumDate }}</h3>
</div>
看起来正确的方法是使用| 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
,因此我们可以将其删除!
试试这个:
var app = angular.module('myApp', ['angular.filter']);
app.controller('myCtrl', ["$scope", "$filter", function ($scope, $filter) {
$scope.groups = [
{ category: 'alpha', id: 2 },
{ category: 'beta', id: 3 },
{ category: 'gamma', id: 0 },
{ category: 'alpha', id: 4 },
{ category: 'beta', id: 5 },
{ category: 'gamma', id: 1 }
];
// retrieves the min 'id' of a collection, used for the group ordering.
// you can use lodash instead. e.g: _.min(arr, 'id')
$scope.min = function (arr) {
return $filter('min')
($filter('map')(arr, 'id'));
}
}]);
<script src="https://code.jquery.com/jquery-3.6.0.min.js"
integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4="
crossorigin="anonymous"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-filter/0.5.17/angular-filter.min.js" integrity="sha512-f2q5tYQJ0pnslHkuVw7tm7GP7E0BF1YLckJjgLU5z4p1vNz78Jv+nPIEKtZerevbt/HwEfYnRrAo9U3u4m0UHw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<div data-ng-app="myApp" data-ng-controller="myCtrl">
<ul ng-repeat="group in groups | groupBy:'category'| toArray:true | orderBy:['category','id']">
<!-- print the group name -->
<li>{{ group.$key }}</li>
<!-- iterate over the group members and order each group by id -->
<li ng-repeat="item in group | orderBy:'id'">
{{ item }}
</li>
</ul>
</div>
我正在使用 angular-filter 中的 groupBy 按日期 属性.
对一组对象进行分组<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>
反转数组的更简单方法是使用 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>
尝试使用 -
<div ng-repeat="(day, dayEvents) in events | groupBy: '-date' ">
P.S- 直到现在我还没有在任何地方使用过 groupBy!但是这个减去的东西与 orderBy 属性配合得很好!
最近遇到了同样的问题。 groupBy
创建了一个对象,但是 orderBy
需要一个数组,所以这里有点古怪。我最终直接从他们的问题页面得到了答案,其中一位作者很好地解释了它,并提供了对我来说基本上 copy/paste 的代码示例。
https://github.com/a8m/angular-filter/issues/57#issuecomment-65041792
我们可以通过在控制器中对数据进行排序并将 groupBy 输出转换为数组来实现这一点。
在控制器中,在将记录发送到视图之前对其进行排序:
$scope.events = $filter('orderBy')(events, '-date');
现在是模板,按排序顺序接收数据。分组后,我们需要将其转换为 Array :
<div ng-repeat="(day, dayEvents) in events | groupBy: 'date' | toArray:true )">
<h3>{{ day | dayEvents[0].date: mediumDate }}</h3>
</div>
看起来正确的方法是使用| 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
,因此我们可以将其删除!
试试这个:
var app = angular.module('myApp', ['angular.filter']);
app.controller('myCtrl', ["$scope", "$filter", function ($scope, $filter) {
$scope.groups = [
{ category: 'alpha', id: 2 },
{ category: 'beta', id: 3 },
{ category: 'gamma', id: 0 },
{ category: 'alpha', id: 4 },
{ category: 'beta', id: 5 },
{ category: 'gamma', id: 1 }
];
// retrieves the min 'id' of a collection, used for the group ordering.
// you can use lodash instead. e.g: _.min(arr, 'id')
$scope.min = function (arr) {
return $filter('min')
($filter('map')(arr, 'id'));
}
}]);
<script src="https://code.jquery.com/jquery-3.6.0.min.js"
integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4="
crossorigin="anonymous"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-filter/0.5.17/angular-filter.min.js" integrity="sha512-f2q5tYQJ0pnslHkuVw7tm7GP7E0BF1YLckJjgLU5z4p1vNz78Jv+nPIEKtZerevbt/HwEfYnRrAo9U3u4m0UHw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<div data-ng-app="myApp" data-ng-controller="myCtrl">
<ul ng-repeat="group in groups | groupBy:'category'| toArray:true | orderBy:['category','id']">
<!-- print the group name -->
<li>{{ group.$key }}</li>
<!-- iterate over the group members and order each group by id -->
<li ng-repeat="item in group | orderBy:'id'">
{{ item }}
</li>
</ul>
</div>