Let's start with a global controller like GlobalCtrl which is added to the <body> or <html> tag like ng-controller="GlobalCtrl.
Doing this will enable us to keep the scope of this GlobalCtrl throughout your single page Angular app (as you are using ui-router).
Now, inside your GlobalCtrl define something like this:
$rootScope.globalData = {preventExecution: false}; // This callback will be called everytime you change a page using ui-router state $rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState) { $scope.globalData.preventExecution = false; // Just check for your states here if (toState.name == "home" && fromState.name == "about") { $scope.globalData.preventExecution = true; } });
Now, in your state configuration, you can use this $scope.globalData.preventExecution;
.state('home', { url: '/home', templateUrl: 'partial-home.html', controller: function($scope) { if ($scope.globalData.preventExecution) { return; } console.log('i was called'); } });
Answer to the question: The scope that we refer in the GlobalCtrl and the scope that we use in the State controller, how are they related?
Well, it is a very good question but it's simple. Every time a new scope is created in Angular, it always inherits its parent scope (unless isolated). So when your home state controller instantiated, its scope created using parent state i.e. $rootScope here in this case and we are instantiating the globalData in the $rootScope which is an Object (an Object in Javascript can be used to it's any nested object. Read this). So now when we are setting the globalData.preventExecution true/false, the same data can be used in the $scope of your home state controller. This is how both scopes are related or using the same data.
Answer to the question: is there some flag or setting in the ui-router which can accomplish this in general
If you want to achieve the above behaviour code for multiple states then you can write something like this:
$rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState) { $scope.globalData.preventExecution = false; if (toState.name == "home" && fromState && fromState.preventHomeReExecution) { $scope.globalData.preventExecution = true; } });
Now, your states can be written like this:
.state('about', { url: '/about', templateUrl: 'partial-about.html', preventHomeReExecution: true }) .state('foo', { url: '/foo', templateUrl: 'partial-foo.html', }) .state('bar', { url: '/bar', templateUrl: 'partial-bar.html' preventHomeReExecution: true })
Basically, we are using preventHomeReExecution: true as a flag you wanted.