Removing Class from all children except clicked child on ng-click in Angular

Sammy picture Sammy · Jul 8, 2014 · Viewed 8.1k times · Source

I have a simple list item being parsed with ng-repeat:

<ul>
    <li ng-repeat="item in items" class="commonClass" ng-class="{'on': on_var}" ng-click="on_var=!on_var"> 
   {{item.name}} 
    <li>
</ul>

clicking on a list-item will add the class name 'on' as expected. but I want to remove all other 'on' classes as soon as you click on another list-item and only add it to the one clicked. I come from a jQuery background and I am new to angular. All I want to do is something like this:

$("li.commanClass").click(function(){ 
    $("li.commonClass").removeClass('on');
    $(this).addClass('on');
})

I want to know what is the "angular way" of achieving this result

jsfiddle

Thanks.

Answer

charlietfl picture charlietfl · Jul 8, 2014

In angular you want to pass object references to child scopes as much as possible. This way you can use prototypical object inheritance that can branch down many levels.

Think of a scope as being a model. In the case of ng-repeat it creates a child scope for each element. So if the parent scope holds a model it will be passed as reference to the child scopes. Each of these child scopes will hold a reference to the parent scope model object.

Thus you can do:

<li ng-repeat="item in model.items" 
    ng-class="{'on': model.selected==item}" 
    ng-click="model.selected=item">{{ item.name }}</li> 

Then in controller:

$scope.model = {
        selected: null,
        items = [
            {name: "Apple"}, 
            {name: "Banana"}, 
            {name: "California"}
         ]
    };

Try to avoid using functions as above answer does. These functions will get called many times and will add unnecessary extra overhead.

Valuable post to read: "Thinking in AngularJS" if I have a jQuery background?

DEMO