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

fix($animate): wait two until two digests are over until enabling animations #8846

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 18 additions & 21 deletions src/ngAnimate/animate.js
Original file line number Diff line number Diff line change
Expand Up @@ -411,34 +411,31 @@ angular.module('ngAnimate', ['ng'])

$rootElement.data(NG_ANIMATE_STATE, rootAnimateState);

// disable animations during bootstrap, but once we bootstrapped, wait again
// for another digest until enabling animations. Enter, leave and move require
// a follow-up digest so having a watcher here is enough to let both digests pass.
// However, when any directive or view templates are downloaded then we need to
// handle postpone enabling animations until they are fully completed and then...
var watchFn = $rootScope.$watch(
// Wait until all directive and route-related templates are downloaded and
// compiled. The $templateRequest.totalPendingRequests variable keeps track of
// all of the remote templates being currently downloaded. If there are no
// templates currently downloading then the watcher will still fire anyway.
var deregisterWatch = $rootScope.$watch(
function() { return $templateRequest.totalPendingRequests; },
function(val, oldVal) {
if (oldVal === 0) {
if (val === 0) {
$rootScope.$$postDigest(onApplicationReady);
}
} else if(val === 0) {
// ...when the template has been downloaded we digest twice again until the
// animations are set to enabled (since enter, leave and move require a
// follow-up).
if (val !== 0) return;
deregisterWatch();

// Now that all templates have been downloaded, $animate will wait until
// the post digest queue is empty before enabling animations. By having two
// calls to $postDigest calls we can ensure that the flag is enabled at the
// very end of the post digest queue. Since all of the animations in $animate
// use $postDigest, it's important that the code below executes at the end.
// This basically means that the page is fully downloaded and compiled before
// any animations are triggered.
$rootScope.$$postDigest(function() {
$rootScope.$$postDigest(function() {
$rootScope.$$postDigest(onApplicationReady);
rootAnimateState.running = false;
});
}
});
}
);

function onApplicationReady() {
rootAnimateState.running = false;
watchFn();
}

var globalAnimationCounter = 0;
var classNameFilter = $animateProvider.classNameFilter();
var isAnimatableClassName = !classNameFilter
Expand Down
5 changes: 4 additions & 1 deletion test/ng/directive/ngClassSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -434,7 +434,10 @@ describe('ngClass animations', function() {
});
inject(function($compile, $rootScope, $browser, $rootElement, $animate, $timeout, $document) {

// Animations are enabled right away since there are no remote HTTP template requests
// Animations need to digest twice in order to be enabled regardless if there are no template HTTP requests.
$rootScope.$digest();
digestQueue.shift()();

$rootScope.$digest();
digestQueue.shift()();

Expand Down