Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit 3624e38

Browse files
committed
fix(ngView): use animation promises ensure that only one leave animation occurs at a time
the tracking depended on a local flag variable, which was susceptible to corruption due to race conditions. using promises ensures that the previousLeaveAnimation is nulled out only if it hasn't been canceled yet. Closes #9355 Closes #7606 Closes #9374
1 parent b1ee538 commit 3624e38

File tree

2 files changed

+12
-21
lines changed

2 files changed

+12
-21
lines changed

src/ngRoute/directive/ngView.js

+8-7
Original file line numberDiff line numberDiff line change
@@ -188,27 +188,28 @@ function ngViewFactory( $route, $anchorScroll, $animate) {
188188
link: function(scope, $element, attr, ctrl, $transclude) {
189189
var currentScope,
190190
currentElement,
191-
previousElement,
191+
previousLeaveAnimation,
192192
autoScrollExp = attr.autoscroll,
193193
onloadExp = attr.onload || '';
194194

195195
scope.$on('$routeChangeSuccess', update);
196196
update();
197197

198198
function cleanupLastView() {
199-
if(previousElement) {
200-
previousElement.remove();
201-
previousElement = null;
199+
if(previousLeaveAnimation) {
200+
$animate.cancel(previousLeaveAnimation);
201+
previousLeaveAnimation = null;
202202
}
203+
203204
if(currentScope) {
204205
currentScope.$destroy();
205206
currentScope = null;
206207
}
207208
if(currentElement) {
208-
$animate.leave(currentElement).then(function() {
209-
previousElement = null;
209+
previousLeaveAnimation = $animate.leave(currentElement);
210+
previousLeaveAnimation.then(function() {
211+
previousLeaveAnimation = null;
210212
});
211-
previousElement = currentElement;
212213
currentElement = null;
213214
}
214215
}

test/ngRoute/directive/ngViewSpec.js

+4-14
Original file line numberDiff line numberDiff line change
@@ -845,18 +845,8 @@ describe('ngView animations', function() {
845845
});
846846
});
847847

848-
it('should destroy the previous leave animation if a new one takes place', function() {
849-
module(function($provide) {
850-
$provide.decorator('$animate', function($delegate, $$q) {
851-
var emptyPromise = $$q.defer().promise;
852-
$delegate.leave = function() {
853-
return emptyPromise;
854-
};
855-
return $delegate;
856-
});
857-
});
858-
inject(function ($compile, $rootScope, $animate, $location) {
859-
var item;
848+
it('should destroy the previous leave animation if a new one takes place',
849+
inject(function ($compile, $rootScope, $animate, $location, $timeout) {
860850
var $scope = $rootScope.$new();
861851
element = $compile(html(
862852
'<div>' +
@@ -884,8 +874,8 @@ describe('ngView animations', function() {
884874
$rootScope.$digest();
885875

886876
expect(destroyed).toBe(true);
887-
});
888-
});
877+
})
878+
);
889879
});
890880

891881

0 commit comments

Comments
 (0)