Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I use ng-filter without changing $index on ng-repeat?

Currently if I filter, the $index also updates. So if there are 500 results, and I filter the ranking, also updates. How do I have an index column that doesn't update?

Here's my code:

<input ng-model="query.teamName" /></div>
<table class="table">
  <thead>
    <tr>
      <th>Rank</th>
      <th>Team</th>
      <th>Location</th>
      <th>Score</th>
    </tr>
  </thead>
  <tbody>
    <tr ng-repeat="team in teams | filter:query | orderBy:orderByScore:reverseSort">
      <td><span style="color:white">{{$index+1}}</span></td>
      <td>{{team.teamName}}</td>
      <td>{{team.teamLocation}}</td>
      <td>{{team.teamPoints | number:2}}</td>
    </tr>
  </tbody>
</table>

Controller:

scoreboard.controller('scoreboardCtrl', function ($scope, $filter) {

     $scope.orderByScore = 'teamPoints';
     $scope.reverseSort = true;

     $scope.teams = [
          { "teamName": "motorboat skydive", "teamLocation": "1189 King", "teamPoints": 35.53},
          { "teamName": "the grinders", "teamLocation": "1189 King", "teamPoints": 127.90},
          { "teamName": "team forrec", "teamLocation": "1189 King", "teamPoints": 29.46},
          { "teamName": "bikini finger", "teamLocation": "1189 King", "teamPoints": 21.98},
          { "teamName": "la familia", "teamLocation": "1189 King", "teamPoints": 148.32},
          { "teamName": "darkness is", "teamLocation": "1189 King", "teamPoints": 108.88},
          { "teamName": "grinders", "teamLocation": "1189 King", "teamPoints": 167.95},
          { "teamName": "discarded youth", "teamLocation": "1189 King", "teamPoints": 55.52}
          ];
     };
like image 874
milkman15 Avatar asked Sep 23 '14 18:09

milkman15


People also ask

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.

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 you pass an index in NG-repeat?

Each ng-repeat creates a child scope with the passed data, and also adds an additional $index variable in that scope. So what you need to do is reach up to the parent scope, and use that $index .


Video Answer


1 Answers

Angular filter removes and adds a new array and updates the ng-repeat, so $index will also be updated. Instead you can initialize index, ng-init="idx=$index+1" and use it. ng-init values are never watched and are not updated as well, but $index will change based on the iteration number of the item in the array

<tr ng-repeat="team in teams  | filter:query | orderBy:orderByScore:reverseSort" ng-init="idx = $index+1">
    <td><span>{{idx}}</span></td>

Plnkr

Since index is critical here in your case as it is the rankings best way to handle this could be to add index from the controller itself.

$scope.teams = [
          { "teamName": "motorboat skydive", "teamLocation": "1189 King", "teamPoints": 35.53},
          { "teamName": "the grinders", "teamLocation": "1189 King", "teamPoints": 127.90},
          { "teamName": "team forrec", "teamLocation": "1189 King", "teamPoints": 29.46},
          { "teamName": "bikini finger", "teamLocation": "1189 King", "teamPoints": 21.98},
          { "teamName": "la familia", "teamLocation": "1189 King", "teamPoints": 148.32},
          { "teamName": "darkness is", "teamLocation": "1189 King", "teamPoints": 108.88},
          { "teamName": "grinders", "teamLocation": "1189 King", "teamPoints": 167.95},
          { "teamName": "discarded youth", "teamLocation": "1189 King", "teamPoints": 55.52}
          ]
   .sort(function(itm1, itm2){ return itm2.teamPoints - itm1.teamPoints }) //Sort teams

   .map(function(itm, idx){ itm.index = (idx+1); return itm;  }); //assign rankings

I used native sort Or just use angular orderByFilter itself in your controller to do it for the initial set (and remove the logic of ng-init variable assignment from the view). So you don't run with run time $index issues.

Plnkr2

like image 114
PSL Avatar answered Sep 28 '22 10:09

PSL