Reputation: 4234
I have a button which toggles admin and client mode. I've put it in on the rootscope so I can access it everywhere.
I'm using the angular-ui directive
for toggling.
I've put a watch on this model. But nothing is happening. Any idea what can be wrong?
.run(['$rootScope', '$state', '$stateParams', '$location',
function ($rootScope, $state, $stateParams, $location) {
$rootScope.projectMode = 'Client';
$rootScope.$watch('projectMode', function(){
var path = $location.path();
alert("fire") //Only fire ones when the app starts
if($rootScope.projectMode === 'Client'){
var current = 'client'
var replace = 'admin'
} else {
var current = 'admin'
var replace = 'client'
}
var newUrl = path.replace(current, replace)
$location.url(newUrl);
})
}])
Here's my view.
<div class="btn-group">
<button type="button" class="btn btn-default" ng-model="projectMode" btn-radio="'Client'">Klient</button>
<button type="button" class="btn btn-default" ng-model="projectMode" btn-radio="'Admin'">Admin</button>
</div>
btn-radio
is the angular-ui directive for toggling.
I've checked that the $rootScope.projectMode
is changing. So it must be something wrong with the $watch
.
Upvotes: 4
Views: 7914
Reputation: 62
The Trick won't work for me - i had to apply the rootScope after changing the variable:
//Change rootScope-Varible to break
$rootScope.dbsynchstat = "break";
//Apply to Scope
$rootScope.$apply();
After that i can do something like that in any Controller i want to:
$rootScope.$watch('dbsynchstat', function(){
if($rootScope.dbsynchstat == 'break'){
init();
}
}, true);
Do not forget to add the $rootScope to you're controller.
Upvotes: 0
Reputation: 9845
The real problem is that the projectMode
in your view is not the same projectMode
on the $rootScope
. This is a common problem people have in Angular.
Scopes in Angular are prototypical. If a property isn't found in the current scope, then it looks for the property with the same name in that scope's parent, and so on until it reaches the $rootScope
. So, when your view initializes, it may appear that projectMode
is whatever you initialized it to on $rootScope
.
However, as soon as you change the value of projectMode
, it creates a new value on the controller's scope named projectMode
, which is not the same as $rootScope.projectMode
. So, it makes sense that your $watch
isn't fired... The $rootScope
value isn't changing, only the controller scope's value is changing.
If you'd like to fix it, simply change projectMode
to $root.projectMode
everywhere in your HTML. ($root
inside HTML is how you reference $rootScope
.)
Upvotes: 8
Reputation: 186
Try this - also I would recommend running JSLint
.run(['$rootScope', '$state', '$stateParams', '$location',
function ($rootScope, $state, $stateParams, $location) {
$rootScope.projectMode = 'Client';
var current = '';
var replace = '';
var newUrl = '';
var path = '';
$rootScope.$watch('projectMode', function(){
path = $location.path();
if($rootScope.projectMode === 'Client'){
current = 'client';
replace = 'admin';
}else{
current = 'client';
replace = 'admin';
}
newUrl = path.replace(current, replace);
$location.url(newUrl);
})
}])
I would also suggest using Angular's pub sub pattern and have a service watch for messages you could try using $rootScope.$broadcast and in your service $rootScope.$on and then change you location
Upvotes: 0
Reputation: 103
There's a little known third option for the $watch where it checks for object equality rather than object reference. Set that to true. So try this,
$rootScope.$watch('projectMode', function(){
...your stuff here
}, true);
Upvotes: 6