Search code examples
angularjsng-class

Angular ngClass evaluation method


I might be doing something wrong but I can't figure out what.

  • 1 list of tabs
  • I iterate over elements in list to generate tabs. On click, I set a currentTab to the clicked element

Incriminated code is:

  <li ng-class="{active: !selectedTab}">
    <a href="#" ng-click="selectedTab = null;">First</a>
  </li>
  <li ng-class="{active: selectedTab == tab}" data-ng-repeat='tab in tabs'>
    <a href="#" ng-click="selectedTab = tab;">{{tab}}</a>
  </li>

I simply use ngClass to set the "active" state of my tabs, and to display the appropriate content. The problem is that after first click ngClass seems to give me weird results as if my conditions '!selectedTab' and 'selectedTab == tab' end up all evaluating to 'true' since all tabs end up being active.

Here is a 'non' working example: http://plnkr.co/edit/kk2JmGSBNGVMZ6Wnu1sz?p=preview

Am I doing anything wrong or is there a bug in ngClass? If this is a bug, do you know of any workaround?


Solution

  • The trick is to use $parent in the ng-repeat, because of scope differences.

    <li ng-class="{active: $parent.selectedTab === tab}" data-ng-repeat='tab in tabs'>
      <a href="#" ng-click="$parent.selectedTab = tab;">{{tab}}</a>
    </li>
    

    Here's an updated plunker

    Edit: as per @javaCity's comment below, using a $scope function to set a flag is a good alternative to using $parent as per his plunker

    Why is this so?

    For each item/iteration, ng-repeat creates a new scope, which prototypically inherits from the parent scope, but it also assigns the item's value to a new property on the new child scope. (The name of the new property is the loop variable's name.)

    enter image description here

    Image taken from, and more info available here