From 008df7b9bba9bc87a83c9e689385c7187a602c6b Mon Sep 17 00:00:00 2001 From: Andrew Date: Mon, 13 Apr 2015 13:17:38 -0600 Subject: [PATCH] fix(modal): fix race conditions and memory leaks --- js/angular/service/modal.js | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/js/angular/service/modal.js b/js/angular/service/modal.js index 2e15ed3a8e8..92e6612d052 100644 --- a/js/angular/service/modal.js +++ b/js/angular/service/modal.js @@ -70,10 +70,11 @@ IonicModule '$timeout', '$ionicPlatform', '$ionicTemplateLoader', - '$q', + '$$q', '$log', '$ionicClickBlock', -function($rootScope, $ionicBody, $compile, $timeout, $ionicPlatform, $ionicTemplateLoader, $q, $log, $ionicClickBlock) { + '$window', +function($rootScope, $ionicBody, $compile, $timeout, $ionicPlatform, $ionicTemplateLoader, $$q, $log, $ionicClickBlock, $window) { /** * @ngdoc controller @@ -122,15 +123,16 @@ function($rootScope, $ionicBody, $compile, $timeout, $ionicPlatform, $ionicTempl if (self.scope.$$destroyed) { $log.error('Cannot call ' + self.viewType + '.show() after remove(). Please create a new ' + self.viewType + ' instance.'); - return; + return $$q.when(); } var modalEl = jqLite(self.modalEl); self.el.classList.remove('hide'); $timeout(function() { + if (!self._isShown) return; $ionicBody.addClass(self.viewType + '-open'); - }, 400); + }, 400, false); if (!self.el.parentElement) { modalEl.addClass(self.animation); @@ -145,12 +147,14 @@ function($rootScope, $ionicBody, $compile, $timeout, $ionicPlatform, $ionicTempl if (target && self.positionView) { self.positionView(target, modalEl); // set up a listener for in case the window size changes - ionic.on('resize',function() { - ionic.off('resize',null,window); - self.positionView(target,modalEl); - },window); + + self._onWindowResize = function(ev) { + if (self._isShown) self.positionView(target,modalEl); + }; + $window.addEventListener('resize', self._onWindowResize); } + modalEl.addClass('ng-enter active') .removeClass('ng-leave ng-leave-active'); @@ -163,6 +167,7 @@ function($rootScope, $ionicBody, $compile, $timeout, $ionicPlatform, $ionicTempl ionic.views.Modal.prototype.show.call(self); $timeout(function() { + if (!self._isShown) return; modalEl.addClass('ng-enter-active'); ionic.trigger('resize'); self.scope.$parent && self.scope.$parent.$broadcast(self.viewType + '.shown', self); @@ -171,6 +176,7 @@ function($rootScope, $ionicBody, $compile, $timeout, $ionicPlatform, $ionicTempl }, 20); return $timeout(function() { + if (!self._isShown) return; //After animating in, allow hide on backdrop click self.$el.on('click', function(e) { if (self.backdropClickToClose && e.target === self.el) { @@ -198,9 +204,10 @@ function($rootScope, $ionicBody, $compile, $timeout, $ionicPlatform, $ionicTempl modalEl.addClass('ng-leave'); $timeout(function() { + if (self._isShown) return; modalEl.addClass('ng-leave-active') .removeClass('ng-enter ng-enter-active active'); - }, 20); + }, 20, false); self.$el.off('click'); self._isShown = false; @@ -211,7 +218,7 @@ function($rootScope, $ionicBody, $compile, $timeout, $ionicPlatform, $ionicTempl // clean up event listeners if (self.positionView) { - ionic.off('resize',null,window); + $window.addEventListener('resize', self._onWindowResize); } return $timeout(function() {