I know this question already has an answer, but I was shocked when I realized that the chosen best answer (which I had already implemented in some of my code) doesn't align with the AngularJS documentation.
According to AngularJS Documentation:
Do not use controllers to:
- Manipulate DOM — Controllers should contain only business logic. Putting any presentation logic into Controllers significantly affects its testability. Angular has databinding for most cases and directives to encapsulate manual DOM manipulation.
huston007's answer works great, however, it does not follow this recommendation.
With this as your data input:
$scope.peeps = {
'0': {
'id': 0,
'first_name': 'Tony',
'last_name': 'Martin'
},
'1': {
'id': 1,
'first_name': 'Gerald',
'last_name': 'Johanssen'
},
'2': {
'id': 2,
'first_name': 'Bobby',
'last_name': 'Talksalot'
}
};
And this your html:
<ul>
<li ng-repeat="peep in peeps"
ng-click="addOrRemoveClassFromMe(peep.id)"
ng-class="{selected: selectedPeeps[peep.id]}">
{{peep.first_name}} {{peep.last_name}}
</li>
</ul>
My suggested solution uses an array of objects with the person's id as the key and a booleon as the value. This is linked to in the DOM through the ngClass directive.
//-- create the selected peeps array
$scope.selectedPeeps = {};
//-- add the id to an array with a true-ey value
$scope.addOrRemoveClassFromMe = function(id) {
//-- Set selected peeps as true/false
if($scope.selectedPeeps[id]) {
$scope.selectedPeeps[id] = false;
} else {
$scope.selectedPeeps[id] = true;
}
};
You can check out my codepen here.
I also have another version that removes all of this logic from the controller, leaving only the variable definition, but I thought that might be out of the scope of this question. (codepen.io/joshwhatk/pen/bwmid)
Hope this helps.
this
in theng-click
is not the element (as in jQuery) but the scope. Perhaps you can access the element through the$event
object as:ng-click="selectMe($event)"
and in the controller:$scope.selectMe = function($event)
. – Bowens