问题
I am trying to groupBy a date which is a JS date object. I want to group the data per day.
Any ideas how I can do this in a view?
$scope.data = {
messages: [
{
date: new Date(1432811030 * 1000),
message: 'Some text 01'
},
{
date: new Date(1432731600 * 1000),
message: 'Some text 02'
},
{
date: new Date(1432819703 * 1000),
message: 'Some text 03'
}
]
};
And in my view I use:
<div ng-repeat="(key, value) in data.messages | groupBy: 'date'">
<div>{{ key }}</div>
<div ng-repeat="message in value">
<div>{{ message.message }}</div>
</div>
</div>
I have this angular.filter module included in mu project: https://github.com/a8m/angular-filter
Problem is that I now group per date/time instead of per day. Any idea how?
回答1:
DEMO: http://plnkr.co/edit/djPMu4UH9t9BeGwBcUMI
Screenshot: https://www.dropbox.com/s/9z5t6nsp3x1266s/Screenshot%202015-05-28%2019.50.44.png?dl=0
HTML:
<body ng-app="myApp" ng-controller="myController">
<div ng-repeat="(key, value) in testData.messages">
<div>{{ key }}</div>
<div ng-repeat="message in value">
<div>{{ message }}</div>
</div>
</div>
</body>
JS:
var app = angular.module('myApp', []);
app.controller('myController', function($scope) {
$scope.data = {
messages: [
{
date: new Date(1432811030 * 1000),
message: 'Some text 01'
},
{
date: new Date(1432731600 * 1000),
message: 'Some text 02'
},
{
date: new Date(1432819703 * 1000),
message: 'Some text 03'
}
]
};
$scope.convertTo = function (arr, key, dayWise) {
var groups = {};
for (var i=0;l= arr.length, i<l;i++) {
if (dayWise) {
arr[i][key] = arr[i][key].toLocaleDateString();
}
else {
arr[i][key] = arr[i][key].toTimeString();
}
groups[arr[i][key]] = groups[arr[i][key]] || [];
groups[arr[i][key]].push(arr[i]);
}
return groups;
};
$scope.testData = {};
angular.copy($scope.data, $scope.testData);
$scope.testData.messages = $scope.convertTo($scope.testData.messages, 'date', true);
console.log($scope.testData)
});
回答2:
There are two approaches here. One is to use a group by. The other which is what I'd go for is to pre-group my data by day, and have a "dumb" view which doesn't do the grouping but instead the grouping is done in a service beforehand or at the least in the controller. I'd add a plunkr to demonstrate.
http://plnkr.co/edit/z1Y4147sCw2cCAfunHwg?p=preview
If you have your data like that:
vm.data = [
{day: new Date(1432811030000), msg: 'someText'},
{day: new Date(1432811030000), msg: 'someText2'},
{day: new Date(1432811030000), msg: 'someText3'},
{day: new Date(1432731600000), msg: 'someTextDay2'},
{day: new Date(1432731600000), msg: 'someTextDay2-1'},
{day: new Date(1432731600000), msg: 'someTextDay2-2'},
{day: new Date(1432819703000), msg: 'someTextDay3'},
{day: new Date(1432819703000), msg: 'someTextDay3'}
];
Here is the relevant code:
<ul data-ng-repeat="(key, val) in vm.data | groupBy: 'day'">
Day: {{key}}
<li data-ng-repeat="msg in val">
{{msg.msg}}
</li>
</ul>
And, if on the other hand, you were to pre-group your data, your relevant code in your view would look like this:
<ul data-ng-repeat="(key, val) in vm.groupedData">
Day: {{key}}
<li data-ng-repeat="msg in val">
{{msg.msg}}
</li>
</ul>
and here is the js code that groups them per day:
var groupByDate = function groupByDate(messages){
var grouped = {};
_.forEach(messages, function(msg){
var actualDay = new Date(msg.day - (msg.day % 86400000));
if ( !grouped[actualDay] ){
grouped[actualDay] = [];
}
grouped[actualDay].push(msg);
});
return grouped;
};
来源:https://stackoverflow.com/questions/30508068/ng-repeat-groupby-date-field-per-day