ng-class condition changes, but not updating classes
Asked Answered
C

5

32

I have a very strange issue. I have to set an active class on the appropriate <li> when the $scope.selectedCat == cat.id. The list is generated with ng-repeat. If selectedCat is false, the 'Browse All Categories' list item (outside of ng-repeat) is set to active. setCat() sets the value of the $scope.selectedCat variable:

<div id="cat-list" ng-controller="CatController">
    <li ng-class="{'active': {{selectedCat == false}}}">
        <a>
            <div class="name" ng-click="setCat(false)" >Browse All Categories</div>
        </a>
    </li>
    <li class="has-subcat" ng-repeat="cat in cats | filter:catsearch" ng-class="{'active': {{selectedCat == cat.id}}}">
        <a>
            <div cat class="name" ng-click="setCat({{cat.id}})" ng-bind-html="cat.name | highlight:catsearch"></div>
        </a>
    </li>
</div>

When the page loads, everything works fine (snapshot from FireBug):

<li ng-class="{'active': true}" class="ng-scope active">
<!-- ngRepeat: cat in cats | filter:catsearch -->
<li class="has-subcat ng-isolate-scope" ng-repeat="cat in cats | filter:catsearch" ng-class="{'active': false}">

However when I set $scope.selectedClass to a cat.id value, the condition within ng-class gets evaluated correctly, but ng-class won't update the classes accordingly:

<li ng-class="{'active': false}" class="ng-scope active"> <!--Right here!-->
<!-- ngRepeat: cat in cats | filter:catsearch -->
<li class="has-subcat ng-isolate-scope" ng-repeat="cat in cats | filter:catsearch" ng-class="{'active': true}">

Please note that in the first line active class stays set, while ng-class evaluates to false. In the last line active is not set, while ng-class evaluates to true.

Any ideas why it doesn't work? What's the correct Angular way of doing this?

Constant answered 29/9, 2014 at 6:56 Comment(0)
C
35

Replace:

ng-class="{'active': {{selectedCat == cat.id}}}"

With:

ng-class="{'active': selectedCat == cat.id}"

You never need to nest those curly braces like that, in Angular.

Have a look at the ng-class documentation for some more examples.

Calle answered 29/9, 2014 at 6:58 Comment(1)
You may also use a function that gets the class name if it is dynamic, that would help if you need classes like: active-1 (and -1 depends on something else), just concat would not refresh if the "-1" changes to "-2".Daughtry
A
13

Instead of

ng-class="{'active': {{selectedCat == cat.id}}}"

use

ng-class="{active: selectedCat == cat.id}"
Anemograph answered 29/9, 2014 at 7:0 Comment(1)
I have the single quotes also removed. You don't need that around 'active'. I was not allowed to add it as a comment to your answer, that is why posted as a separate answer. Apology since you felt bad.Anemograph
R
6

Hi i'm also facing the same problem. i solved the problem by the way instead of assigning the value directly to ng-class, call the separate method and return the value.

ex :

ng-class="getStyleClass(cat)"

$scope.getStyleClass = function(cat)  {   
      return "active: selectedCat == cat.id";  
}

roughly i coded. please change the method as per your requirement.

Rendon answered 29/7, 2015 at 6:29 Comment(2)
That's crazy. Thought it would behave the same as when using the [well unknown] syntax of ng-class="{ true: 'active', false: 'muted' }[x == y]". This syntax always rebinds / debinds the classes.Coronal
Scratch that. This isn't working for me. It still puts the style on each [selected] item, but when $scope.selected changes (via my isSelected(date) -> return this.selected === date) each of the consecutively clicked items retain this style upon other selections.Coronal
R
2

Expanding on the answer @Cerbrus gave:

Replace:

ng-class="{'active': {{selectedCat == cat.id}}}"

With:

ng-class="{'active': selectedCat == cat.id}"

I had an issue with an expression using a filter, that would not evaluate properly without double curly braces {{ }}.

Example: ng-class="{'active': {{ selectedCat | filter:catType }} == cat.id}"

I solved it by putting parentheses instead of curly braces.

Solution: ng-class="{'active': ( selectedCat | filter:catType ) == cat.id}"

Rohde answered 30/3, 2016 at 4:54 Comment(0)
Z
0

Did you solve it?

In my opinion you should use

ng-class="{'active': {{controller.selectedCat == cat.id}}}"

With:

ng-class="{'active': controller.selectedCat == cat.id}"

this will help you.

Zerk answered 20/7, 2019 at 11:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.