Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angularjs OrderBy on ng-repeat doesn't work

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.

like image 604
Arthur Avatar asked May 28 '14 19:05

Arthur


People also ask

What can I use instead of NG-repeat?

You can consider using transclusion inside a custom directive, to achieve the behavior you are looking for without using ng-repeat.

How do I filter in NG-repeat?

The ng-repeat values can be filtered according to the ng-model in AngularJS by using the value of the input field as an expression in a filter. We can set the ng-model directive on an input field to filter ng-repeat values.

Does ng-repeat create a new scope?

Directives that Create Scopes In most cases, directives and scopes interact but do not create new instances of scope. However, some directives, such as ng-controller and ng-repeat, create new child scopes and attach the child scope to the corresponding DOM element.

Where is the last element in NG-repeat?

You can use $last variable within ng-repeat directive. Take a look at doc. Where computeCssClass is function of controller which takes sole argument and returns 'last' or null .


2 Answers

$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.

like image 166
Jerrad Avatar answered Oct 23 '22 11:10

Jerrad


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.

like image 24
Preview Avatar answered Oct 23 '22 11:10

Preview