Reputation: 2991
This is my angular code.. (to describe the problem I'm getting is that the nested ng-repeat for buttons repeats is behavior (when clicked) to all the "jobs" listed..
<div class="row" ng-repeat="job in jobs">
<div class="btn-group btn-group-justified" role="group">
<div class="btn-group" role="group" ng-repeat="status in job.statuscollection">
<button type="button" class="btn btn-default" ng-class="{ 'btn-info': $index == selectedIndex }" ng-click="itemClicked($index)">{{status.name}}</button>
</div>
</div>
</div>
Here's my js code..
$scope.jobs = [
{
_id: new Date().toISOString(),
statuscollection: [
{ name: "Off-Site"},
{ name: "Enroute" },
{ name: "On-Site" },
]
docType: "job",
},
{
_id: new Date().toISOString(),
statuscollection: [
{ name: "Off-Site"},
{ name: "Enroute" },
{ name: "On-Site" },
]
docType: "job",
}];
This here's my ng-click function..
$scope.itemClicked = function ($index) {
$scope.selectedIndex = $index;
console.log($scope.jobs[$index]);
}
I have more than just one job, I included only one here into the code to have less of it. but when the browser generates this data in the correct way, clicking on one of the "job's" buttons does the same thing for each job.
Meaning, if I click the button "on-site" for one job, it is duplicated for all the jobs.. how can I make it so that clicking just one of the job's buttons does it only for that job, and not all of them?
Upvotes: 2
Views: 660
Reputation: 8436
The proper Angular approach to track indices across multiple ngRepeats
is to use ngInit
to create a local variable that aliases $index
for each instance of ngRepeat
. Using $parent
to acquire its $index
position is generally discouraged.
And in the example below, we have two ngRepeats
and therefore two aliased index variables: outerIndex
and innerIndex
:
<tbody ng-repeat="country in countries" ng-init="outerIndex = $index">
<tr ng-repeat="city in country.cities" ng-init="innerIndex = $index">
<td>{{city}}</td>
<td>{{country.name}}</td>
<td>({{outerIndex}}, {{innerIndex}})</td>
</tr>
</tbody>
Plunker: http://plnkr.co/edit/VA1XWWrG3pghEcWli06F
After understanding more of the context behind the question, it actually makes more sense for the OP to set an isActive
property on the selected object instead attempting to track and match indices. That said the approach noted above is still valid and applicable for tracking indices across multiple ngRepeats
$scope.itemClicked = function (status, job) {
if (status.isActive) {
status.isActive = false;
} else {
angular.forEach(job.statuscollection, function(status) {
status.isActive = false;
});
status.isActive = true;
}
}
Updated plunker: http://plnkr.co/edit/v70fY30PjoTXCrhOPVZB
Upvotes: 1
Reputation: 8971
Use $parent.$index
instead of $index
to refer to the outer ng-repeated loop (the job loop, that is):
<button type="button" class="btn btn-default" ng-class="{ 'btn-info': $parent.index == selectedIndex }" ng-click="itemClicked($parent.$index)">{{status.name}}</button>
$index
is the index of the inner loop.
$parent.$index
is the index of the outer loop.
Upvotes: 1