Reputation: 705
I was attempting to get AngularJs to apply an active
class on a nav section depending upon the active route. My solution works fine but I noticed a curious behaviour -- more on that below. For now, here's how the active class is set in the HTML:
<ul class="menu" ng-controller="ControllerHeader">
<li><a ng-class="{ active: isActive('/foo') }" href="#/foo">foo</a></li>
<li><a ng-class="{ active: isActive('/bar') }" href="#/bar">bar</a></li>
<li><a ng-class="{ active: isActive('/baz') }" href="#/baz">baz</a></li>
</ul>
ControllerHeader
and isActive
are defined as given:
var app = angular.module('app', [ ]);
app.controller( 'ControllerHeader', ['$scope', '$location',
function ($scope, $location) {
$scope.isActive = function (location) {
// multiple logging occurs: exactly 3*3 times
console.log(location, $location.path());
return location === $location.path();
};
}
] );
The issue I've noticed is that isActive
above is called 3 * 3 times! Could someone please explain why? How can I fix it that such that it is called once per item only?
Upvotes: 0
Views: 5008
Reputation: 19193
If you are using Angular 1.3+, you can use the ::
operator to only evaluate the expression once:
<ul class="menu" ng-controller="ControllerHeader">
<li><a ng-class="::{ active: isActive('/foo') }" href="#/foo">foo</a></li>
<li><a ng-class="::{ active: isActive('/bar') }" href="#/bar">bar</a></li>
<li><a ng-class="::{ active: isActive('/baz') }" href="#/baz">baz</a></li>
</ul>
If you are using an older version of Angular, you can use a third party library such as bindonce
As for why this is happening without binding once, indeed it is covered by many other questions. If you want the class to be dynamically set depending on angular context, Angular need to execute the function to check its value. That is called executing the watchers during a digest cycle, and this is done often.
Upvotes: 4
Reputation: 14027
All expression that you use in AngularJS get evaluated multiple times when a digest cycle runs. This is done for dirty checking which validates whether the current value of expression is different from the last value.
Upvotes: 0