Skip to content

Commit 008df7b

Browse files
committed
fix(modal): fix race conditions and memory leaks
1 parent fdca73a commit 008df7b

File tree

1 file changed

+17
-10
lines changed

1 file changed

+17
-10
lines changed

js/angular/service/modal.js

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,11 @@ IonicModule
7070
'$timeout',
7171
'$ionicPlatform',
7272
'$ionicTemplateLoader',
73-
'$q',
73+
'$$q',
7474
'$log',
7575
'$ionicClickBlock',
76-
function($rootScope, $ionicBody, $compile, $timeout, $ionicPlatform, $ionicTemplateLoader, $q, $log, $ionicClickBlock) {
76+
'$window',
77+
function($rootScope, $ionicBody, $compile, $timeout, $ionicPlatform, $ionicTemplateLoader, $$q, $log, $ionicClickBlock, $window) {
7778

7879
/**
7980
* @ngdoc controller
@@ -122,15 +123,16 @@ function($rootScope, $ionicBody, $compile, $timeout, $ionicPlatform, $ionicTempl
122123

123124
if (self.scope.$$destroyed) {
124125
$log.error('Cannot call ' + self.viewType + '.show() after remove(). Please create a new ' + self.viewType + ' instance.');
125-
return;
126+
return $$q.when();
126127
}
127128

128129
var modalEl = jqLite(self.modalEl);
129130

130131
self.el.classList.remove('hide');
131132
$timeout(function() {
133+
if (!self._isShown) return;
132134
$ionicBody.addClass(self.viewType + '-open');
133-
}, 400);
135+
}, 400, false);
134136

135137
if (!self.el.parentElement) {
136138
modalEl.addClass(self.animation);
@@ -145,12 +147,14 @@ function($rootScope, $ionicBody, $compile, $timeout, $ionicPlatform, $ionicTempl
145147
if (target && self.positionView) {
146148
self.positionView(target, modalEl);
147149
// set up a listener for in case the window size changes
148-
ionic.on('resize',function() {
149-
ionic.off('resize',null,window);
150-
self.positionView(target,modalEl);
151-
},window);
150+
151+
self._onWindowResize = function(ev) {
152+
if (self._isShown) self.positionView(target,modalEl);
153+
};
154+
$window.addEventListener('resize', self._onWindowResize);
152155
}
153156

157+
154158
modalEl.addClass('ng-enter active')
155159
.removeClass('ng-leave ng-leave-active');
156160

@@ -163,6 +167,7 @@ function($rootScope, $ionicBody, $compile, $timeout, $ionicPlatform, $ionicTempl
163167
ionic.views.Modal.prototype.show.call(self);
164168

165169
$timeout(function() {
170+
if (!self._isShown) return;
166171
modalEl.addClass('ng-enter-active');
167172
ionic.trigger('resize');
168173
self.scope.$parent && self.scope.$parent.$broadcast(self.viewType + '.shown', self);
@@ -171,6 +176,7 @@ function($rootScope, $ionicBody, $compile, $timeout, $ionicPlatform, $ionicTempl
171176
}, 20);
172177

173178
return $timeout(function() {
179+
if (!self._isShown) return;
174180
//After animating in, allow hide on backdrop click
175181
self.$el.on('click', function(e) {
176182
if (self.backdropClickToClose && e.target === self.el) {
@@ -198,9 +204,10 @@ function($rootScope, $ionicBody, $compile, $timeout, $ionicPlatform, $ionicTempl
198204
modalEl.addClass('ng-leave');
199205

200206
$timeout(function() {
207+
if (self._isShown) return;
201208
modalEl.addClass('ng-leave-active')
202209
.removeClass('ng-enter ng-enter-active active');
203-
}, 20);
210+
}, 20, false);
204211

205212
self.$el.off('click');
206213
self._isShown = false;
@@ -211,7 +218,7 @@ function($rootScope, $ionicBody, $compile, $timeout, $ionicPlatform, $ionicTempl
211218

212219
// clean up event listeners
213220
if (self.positionView) {
214-
ionic.off('resize',null,window);
221+
$window.addEventListener('resize', self._onWindowResize);
215222
}
216223

217224
return $timeout(function() {

0 commit comments

Comments
 (0)