From 365fd5d0482f1f11eb9ecfc0dca5d7c2bac3c02c Mon Sep 17 00:00:00 2001 From: David Li Date: Tue, 4 Nov 2014 12:25:07 -0500 Subject: [PATCH] fix($rootScope): remove history event handler when app is torn down Remember the popstate and hashchange handler registered with window when the application bootstraps, and remove it when the application is torn down Closes #9897 --- src/ng/browser.js | 10 ++++++++++ src/ng/rootScope.js | 7 ++++++- src/ngMock/angular-mocks.js | 1 + 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/ng/browser.js b/src/ng/browser.js index 37f3ab297505..fef1899a3885 100644 --- a/src/ng/browser.js +++ b/src/ng/browser.js @@ -293,6 +293,16 @@ function Browser(window, document, $log, $sniffer) { return callback; }; + /** + * @private + * Remove popstate and hashchange handler from window. + * + * NOTE: this api is intended for use only by $rootScope. + */ + self.$$applicationDestroyed = function() { + jqLite(window).off('hashchange popstate', cacheStateAndFireUrlChange); + }; + /** * Checks whether the url has changed outside of Angular. * Needs to be exported to be able to check for changes that have been done in sync, diff --git a/src/ng/rootScope.js b/src/ng/rootScope.js index b98dccca8a4f..00d6518e7143 100644 --- a/src/ng/rootScope.js +++ b/src/ng/rootScope.js @@ -861,7 +861,12 @@ function $RootScopeProvider() { this.$broadcast('$destroy'); this.$$destroyed = true; - if (this === $rootScope) return; + + if (this === $rootScope) { + //Remove handlers attached to window when $rootScope is removed + $browser.$$applicationDestroyed(); + return; + } for (var eventName in this.$$listenerCount) { decrementListenerCount(this, this.$$listenerCount[eventName], eventName); diff --git a/src/ngMock/angular-mocks.js b/src/ngMock/angular-mocks.js index 71eedb3318f4..ef0804c85ea9 100644 --- a/src/ngMock/angular-mocks.js +++ b/src/ngMock/angular-mocks.js @@ -57,6 +57,7 @@ angular.mock.$Browser = function() { return listener; }; + self.$$applicationDestroyed = angular.noop; self.$$checkUrlChange = angular.noop; self.cookieHash = {};