Reputation: 5148
I'm trying to use AngularJS for my first project (a tournaments manager) and the orderBy
filter on ng-repeat
doesn't work :( I have read all the documentation about that, but nothing to do :/
So, I have vars defined on $scope
like that :
$scope.order_item = "count_win";
$scope.order_reverse = false;
$scope.teams = {
100 : {
id: 100,
name: "XXX",
count_win: 1,
count_loose: 2,
goal_average: 1,
},
200 : {
id: 200,
name: "XXX",
count_win: 1,
count_loose: 2,
goal_average: 1,
},
[...]
};
Now, on my view i'm trying to reorder (first with only one order item) but never work...
<tr ng-repeat="team in teams | orderBy:order_item:order_reverse">
<td>{{team.name}}</td>
<td>{{team.count_loose}}</td>
<td>{{team.goal_average}}</td>
</tr>
The second time, I want to reorder from 2 pieces of information: count_win
and goal_average
if first are equal.. I try to replace $scope.order_item
like that, but if with one the code doesn't work, he'll never work with 2...
$scope.order_item = ['count_win','goal_average'];
Thank you all for reading and sorry for the post size.
Upvotes: 35
Views: 96557
Reputation: 35806
You don't have to create a scope parameter for your orderBy, you can directly do this in your markup if you are dealing with arrays.
<tr ng-repeat="team in teams | orderBy:count_win:false">
With two parameters, you should just do
<tr ng-repeat="team in teams | orderBy:['count_win','goal_average']">
After for a more complex order, you could create a function in your scope like so :
$scope.customOrder = function (team) {
//custom
}
And just call it like
<tr ng-repeat="team in teams | orderBy:customOrder">
Like @Jerrad said, ng-repeat
only works with arrays, so you need to convert your teams object into an array to get it work properly.
Upvotes: 11
Reputation: 5290
$scope.teams
isn't an array (it's an object of objects), and the orderBy
filter only works with arrays. If you make $scope.teams
an array, it will work:
$scope.teams = [
{
id: 100,
name: "team1",
count_win: 3,
count_loose: 2,
goal_average: 2,
},
{
id: 200,
name: "team2",
count_win: 3,
count_loose: 2,
goal_average: 1,
},
{
id: 300,
name: "team3",
count_win: 1,
count_loose: 2,
goal_average: 1,
}
];
Or, you can add a special filter that works on objects, like this (borrowed from here):
app.filter('orderObjectBy', function() {
return function(items, field, reverse) {
var filtered = [];
angular.forEach(items, function(item) {
filtered.push(item);
});
filtered.sort(function (a, b) {
return (a[field] > b[field] ? 1 : -1);
});
if(reverse) filtered.reverse();
return filtered;
};
});
And use it like this:
<tr ng-repeat="team in teams | orderObjectBy:order_item:order_reverse">
Note that this custom filter will not work with an array of sort orders as in the second part of your question.
Upvotes: 58
Reputation: 1845
ng-repeat works only on arrays, not on JSON objects. This was already discussed here: Angular - Can't make ng-repeat orderBy work
You either have to change the JSON object to an Array, or to convert it on the fly. The controller could then look like this:
var app = angular.module('app', []);
app.controller('Ctrl', function ($scope) {
$scope.teams = [
{
id: 100,
name: "A Team",
count_win: 1,
count_loose: 2,
goal_average: 1
},
{
id: 200,
name: "C Team",
count_win: 2,
count_loose: 3,
goal_average: 4
},
{
id: 300,
name: "B Team",
count_win: 4,
count_loose: 1,
goal_average: 8
}
];
$scope.predicate = 'name';
});
I created a fiddle here with a demo containing your data:
Upvotes: 8