From e9881991ca0a5019d3a4215477738ed247898ba0 Mon Sep 17 00:00:00 2001 From: Matias Niemelä Date: Fri, 21 Feb 2014 03:43:50 -0500 Subject: fix($animate): ensure that animateable directives cancel expired leave animations If enter -> leave -> enter -> leave occurs then the first leave animation will animate alongside the second. This causes the very first DOM node (the view in ngView for example) to animate at the same time as the most recent DOM node which ends up being an undesired effect. This fix takes care of this issue. Closes #5886 --- src/ng/directive/ngIf.js | 17 +++++++++++------ src/ng/directive/ngInclude.js | 12 ++++++++++-- src/ng/directive/ngSwitch.js | 25 ++++++++++++++++++++++--- src/ngAnimate/animate.js | 21 +++++++++++++++++++++ src/ngRoute/directive/ngView.js | 12 ++++++++++-- 5 files changed, 74 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/ng/directive/ngIf.js b/src/ng/directive/ngIf.js index 000fba82..a31015b2 100644 --- a/src/ng/directive/ngIf.js +++ b/src/ng/directive/ngIf.js @@ -84,7 +84,7 @@ var ngIfDirective = ['$animate', function($animate) { restrict: 'A', $$tlb: true, link: function ($scope, $element, $attr, ctrl, $transclude) { - var block, childScope; + var block, childScope, previousElements; $scope.$watch($attr.ngIf, function ngIfWatchAction(value) { if (toBoolean(value)) { @@ -102,14 +102,19 @@ var ngIfDirective = ['$animate', function($animate) { }); } } else { - - if (childScope) { + if(previousElements) { + previousElements.remove(); + previousElements = null; + } + if(childScope) { childScope.$destroy(); childScope = null; } - - if (block) { - $animate.leave(getBlockElements(block.clone)); + if(block) { + previousElements = getBlockElements(block.clone); + $animate.leave(previousElements, function() { + previousElements = null; + }); block = null; } } diff --git a/src/ng/directive/ngInclude.js b/src/ng/directive/ngInclude.js index 29e3abce..272e199a 100644 --- a/src/ng/directive/ngInclude.js +++ b/src/ng/directive/ngInclude.js @@ -177,15 +177,23 @@ var ngIncludeDirective = ['$http', '$templateCache', '$anchorScroll', '$animate' return function(scope, $element, $attr, ctrl, $transclude) { var changeCounter = 0, currentScope, + previousElement, currentElement; var cleanupLastIncludeContent = function() { - if (currentScope) { + if(previousElement) { + previousElement.remove(); + previousElement = null; + } + if(currentScope) { currentScope.$destroy(); currentScope = null; } if(currentElement) { - $animate.leave(currentElement); + $animate.leave(currentElement, function() { + previousElement = null; + }); + previousElement = currentElement; currentElement = null; } }; diff --git a/src/ng/directive/ngSwitch.js b/src/ng/directive/ngSwitch.js index 92594978..378c0b50 100644 --- a/src/ng/directive/ngSwitch.js +++ b/src/ng/directive/ngSwitch.js @@ -138,12 +138,31 @@ var ngSwitchDirective = ['$animate', function($animate) { var watchExpr = attr.ngSwitch || attr.on, selectedTranscludes, selectedElements, + previousElements, selectedScopes = []; scope.$watch(watchExpr, function ngSwitchWatchAction(value) { - for (var i= 0, ii=selectedScopes.length; i 0) { + if(previousElements) { + for (i = 0; i < ii; i++) { + previousElements[i].remove(); + } + previousElements = null; + } + + previousElements = []; + for (i= 0; i