Pneumokok Pneumokok - 4 months ago 9
AngularJS Question

Strage behavior of ng-class when ng-if is used

I have this piece of code:

....
<article class="collapse navbar-collapse">
<ul ng-if="isLogged()" class="nav navbar-nav">
<li ng-class="{'active': activeUrl === 'projects'}">
<a href="#/projects" ng-click="activeUrl='projects'">Projects</a>
</li>
<li ng-if="isAdmin()" ng-class="{'active': activeUrl === 'admin'}">
<a href="#/admin" ng-click="activeUrl='admin'">Administration</a>
</li>
</ul>
</article>


And it should add
active
class when link is clicked. It worked very well until I added
ng-if
expressions, which mock user authentication. Now when it adds
active
class once, it doesn't remove this class when another navigation link is clicked - it looks like 2 pages are opened in the same time.
There is
applicationController
which has mock functions:

applicationController= function($scope, Restangular, userService){
$scope.activeUrl = "admin";
$scope.data = {
user: {
email: undefined,
password: undefined
}
};

$scope.login = function(user){
//login mock
};

$scope.isLogged = function(){
return userService.isLogged();
};

$scope.isAdmin = function(){
return userService.isAdmin();
};
};


And
userService
has logic which determine if user is authenticated and if is administrator. I don't think that
ng-if
with
ng-class
in one HTML element is something unusual, that's why I think I must made some simple mistake which I can't see. Is scope recreated after any click? I would be very happy if anybody helps me - thank you in advance!
Update: solution with @ptwo help, I need
$parent
and with Administration
$parent.$parent
:

<article class="collapse navbar-collapse">
<ul ng-if="isLogged()" class="nav navbar-nav">
<li ng-class="{'active': $parent.activeUrl === 'projects'}">
<a href="#/projects" ng-click="$parent.activeUrl='projects'">Projects</a>
</li>
<li ng-if="isAdmin()" ng-class="{'active': $parent.$parent.activeUrl === 'admin'}">
<a href="#/admin" ng-click="$parent.$parent.activeUrl='admin'">Administration</a>
</li>
</ul>
</article>


Update 2 with solution without direct accessing
$parent
, but with
data
object in
applicationController
which allows me to access
activeUrl
:

<article class="collapse navbar-collapse">
<ul ng-if="isLogged()" class="nav navbar-nav">
<li ng-class="{'active': data.activeUrl === 'projects'}">
<a href="#/projects" ng-click="data.activeUrl='projects'">Projects</a>
</li>
<li ng-if="isAdmin()" ng-class="{'active': data.activeUrl === 'admin'}">
<a href="#/admin" ng-click="data.activeUrl='admin'">Administration</a>
</li>
</ul>
</article>

applicationController= function($scope, Restangular, userService){
$scope.data = {
activeUrl: "admin",
user: {
email: undefined,
password: undefined
}
};
....

Answer

When you use ng-if it adds a scope of its own hence on click the activeUrl is set on a child scope of the controller. Try using $parent.activeUrl='admin' it should work