|
73 | 73 | * When the `on` expression value changes and an animation is triggered then each of the elements within
|
74 | 74 | * will all animate without the block being applied to child elements.
|
75 | 75 | *
|
| 76 | + * ## Are animations run when the application starts? |
| 77 | + * No they are not. When an application is bootstrapped Angular will disable animations from running to avoid |
| 78 | + * a frenzy of animations from being triggered as soon as the browser has rendered the screen. For this to work, |
| 79 | + * Angular will wait for two digest cycles until enabling animations. From there on, any animation-triggering |
| 80 | + * layout changes in the application will trigger animations as normal. |
| 81 | + * |
| 82 | + * In addition, upon bootstrap, if the routing system or any directives or load remote data (via $http) then Angular |
| 83 | + * will automatically extend the wait time to enable animations once **all** of the outbound HTTP requests |
| 84 | + * are complete. |
| 85 | + * |
76 | 86 | * <h2>CSS-defined Animations</h2>
|
77 | 87 | * The animate service will automatically apply two CSS classes to the animated element and these two CSS classes
|
78 | 88 | * are designed to contain the start and end CSS styling. Both CSS transitions and keyframe animations are supported
|
@@ -396,24 +406,40 @@ angular.module('ngAnimate', ['ng'])
|
396 | 406 | }
|
397 | 407 |
|
398 | 408 | $provide.decorator('$animate',
|
399 |
| - ['$delegate', '$$q', '$injector', '$sniffer', '$rootElement', '$$asyncCallback', '$rootScope', '$document', |
400 |
| - function($delegate, $$q, $injector, $sniffer, $rootElement, $$asyncCallback, $rootScope, $document) { |
| 409 | + ['$delegate', '$$q', '$injector', '$sniffer', '$rootElement', '$$asyncCallback', '$rootScope', '$document', '$templateRequest', |
| 410 | + function($delegate, $$q, $injector, $sniffer, $rootElement, $$asyncCallback, $rootScope, $document, $templateRequest) { |
401 | 411 |
|
402 |
| - var globalAnimationCounter = 0; |
403 | 412 | $rootElement.data(NG_ANIMATE_STATE, rootAnimateState);
|
404 | 413 |
|
405 | 414 | // disable animations during bootstrap, but once we bootstrapped, wait again
|
406 |
| - // for another digest until enabling animations. The reason why we digest twice |
407 |
| - // is because all structural animations (enter, leave and move) all perform a |
408 |
| - // post digest operation before animating. If we only wait for a single digest |
409 |
| - // to pass then the structural animation would render its animation on page load. |
410 |
| - // (which is what we're trying to avoid when the application first boots up.) |
411 |
| - $rootScope.$$postDigest(function() { |
412 |
| - $rootScope.$$postDigest(function() { |
413 |
| - rootAnimateState.running = false; |
414 |
| - }); |
415 |
| - }); |
| 415 | + // for another digest until enabling animations. Enter, leave and move require |
| 416 | + // a follow-up digest so having a watcher here is enough to let both digests pass. |
| 417 | + // However, when any directive or view templates are downloaded then we need to |
| 418 | + // handle postpone enabling animations until they are fully completed and then... |
| 419 | + var watchFn = $rootScope.$watch( |
| 420 | + function() { return $templateRequest.totalPendingRequests; }, |
| 421 | + function(val, oldVal) { |
| 422 | + if (oldVal === 0) { |
| 423 | + if (val === 0) { |
| 424 | + $rootScope.$$postDigest(onApplicationReady); |
| 425 | + } |
| 426 | + } else if(val === 0) { |
| 427 | + // ...when the template has been downloaded we digest twice again until the |
| 428 | + // animations are set to enabled (since enter, leave and move require a |
| 429 | + // follow-up). |
| 430 | + $rootScope.$$postDigest(function() { |
| 431 | + $rootScope.$$postDigest(onApplicationReady); |
| 432 | + }); |
| 433 | + } |
| 434 | + } |
| 435 | + ); |
416 | 436 |
|
| 437 | + function onApplicationReady() { |
| 438 | + rootAnimateState.running = false; |
| 439 | + watchFn(); |
| 440 | + } |
| 441 | + |
| 442 | + var globalAnimationCounter = 0; |
417 | 443 | var classNameFilter = $animateProvider.classNameFilter();
|
418 | 444 | var isAnimatableClassName = !classNameFilter
|
419 | 445 | ? function() { return true; }
|
|
0 commit comments