I have my angular app set up with an ng-view directive in the index.html, with views configured with $routeProvider config and each view having its own controller. In one view controller, I have a $rootScope.$on listener that watches for events. I expect this listener to no longer run when I change views, but this is not the case. The watch still keeps calling code when it is triggered, even when I have switched to a view that is no longer using that controller.
I have set up some test code to listen to the $destroy event, and I can see that the $destroy event is being triggered, but the listener function still runs. I have printed out $scope.$id in both the watch function and the $destroy event listener, and I can see that the IDs match. So it seems that even after the $destroy event occurs for the specific scope, the $on listener on it still keep running. Why is this the case? I was under the impression that when navigating to a different view, or in any case the controller is destroyed, then listeners for it are cleared.
Plnkr: http://plnkr.co/edit/TxssxQJY5PVLTAIAr4xD?p=preview
var animateApp = angular.module('animateApp', ['ngRoute', 'ngAnimate']);
animateApp.config(function($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'page-home.html',
controller: 'mainController'
})
.when('/about', {
templateUrl: 'page-about.html',
controller: 'aboutController'
})
.when('/contact', {
templateUrl: 'page-contact.html',
controller: 'contactController'
});
});
angular.module('animateApp').service('service', ['$interval', '$rootScope', service]);
function service ($interval, $rootScope) {
var service = {};
service.abc = 1;
$interval(function() {
service.abc++;
$rootScope.$broadcast('service.abc', service.abc);
}, 500);
return service;
}
animateApp.controller('mainController', function($scope, $rootScope, service) {
$scope.pageClass = 'page-home';
$scope.$on('$destroy', function iVeBeenDismissed() {
console.log('goodbye ' + $scope.$id);
// release resources, cancel request...
})
$rootScope.$on('service.abc', function (newval) {
console.log($scope.$id);
})
});
animateApp.controller('aboutController', function($scope) {
$scope.pageClass = 'page-about';
});
animateApp.controller('contactController', function($scope) {
$scope.pageClass = 'page-contact';
});
You should add a
$destroy
event listener in your controllers:With this you'll manually make sure that there will be no more active $watchers on inactive controllers.