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}
];
};
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.
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.
You can consider using transclusion inside a custom directive, to achieve the behavior you are looking for without using 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 .
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With