Skip to content

Commit

Permalink
fix($rootScope): remove history event handler when app is torn down
Browse files Browse the repository at this point in the history
Remember the popstate and hashchange handler registered with window
when the application bootstraps, and remove it when the application
is torn down

Closes angular#9897
  • Loading branch information
randombk committed Nov 4, 2014
1 parent 0f7bcfd commit 03118f6
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 5 deletions.
14 changes: 10 additions & 4 deletions src/ng/browser.js
Original file line number Diff line number Diff line change
Expand Up @@ -222,10 +222,16 @@ function Browser(window, document, $log, $sniffer) {
var urlChangeListeners = [],
urlChangeInit = false;

function cacheStateAndFireUrlChange() {
/**
* @private
* Event handler for hashchange and popstate events.
* Note: this method is used only by $rootScope to remove the handler when an app
* is torn down. (See https://github.com/angular/angular.js/issues/9897)
*/
self.cacheStateAndFireUrlChange = function() {
cacheState();
fireUrlChange();
}
};

// This variable should be used *only* inside the cacheState function.
var lastCachedState = null;
Expand Down Expand Up @@ -282,9 +288,9 @@ function Browser(window, document, $log, $sniffer) {
// changed by push/replaceState

// html5 history api - popstate event
if ($sniffer.history) jqLite(window).on('popstate', cacheStateAndFireUrlChange);
if ($sniffer.history) jqLite(window).on('popstate', self.cacheStateAndFireUrlChange);
// hashchange event
jqLite(window).on('hashchange', cacheStateAndFireUrlChange);
jqLite(window).on('hashchange', self.cacheStateAndFireUrlChange);

urlChangeInit = true;
}
Expand Down
9 changes: 8 additions & 1 deletion src/ng/rootScope.js
Original file line number Diff line number Diff line change
Expand Up @@ -861,7 +861,14 @@ function $RootScopeProvider() {

this.$broadcast('$destroy');
this.$$destroyed = true;
if (this === $rootScope) return;

if (this === $rootScope) {
//Remove handlers attached to window when $rootScope is removed
//See https://github.com/angular/angular.js/issues/9897
jqLite(window).unbind("popstate", $browser.cacheStateAndFireUrlChange);
jqLite(window).unbind("hashchange", $browser.cacheStateAndFireUrlChange);
return;
}

for (var eventName in this.$$listenerCount) {
decrementListenerCount(this, this.$$listenerCount[eventName], eventName);
Expand Down

0 comments on commit 03118f6

Please sign in to comment.