diff --git a/modules/@angular/core/src/animation/animation_queue.ts b/modules/@angular/core/src/animation/animation_queue.ts index 8c9b119874..260b828c50 100644 --- a/modules/@angular/core/src/animation/animation_queue.ts +++ b/modules/@angular/core/src/animation/animation_queue.ts @@ -17,6 +17,15 @@ export function queueAnimation(player: AnimationPlayer) { /** @internal */ export function triggerQueuedAnimations() { + // this code is wrapped into a single promise such that the + // onStart and onDone player callbacks are triggered outside + // of the digest cycle of animations + if (_queuedAnimations.length) { + Promise.resolve(null).then(_triggerAnimations); + } +} + +function _triggerAnimations() { for (var i = 0; i < _queuedAnimations.length; i++) { var player = _queuedAnimations[i]; player.play(); diff --git a/modules/@angular/core/test/animation/animation_integration_spec.ts b/modules/@angular/core/test/animation/animation_integration_spec.ts index f6c594c620..21cf07093e 100644 --- a/modules/@angular/core/test/animation/animation_integration_spec.ts +++ b/modules/@angular/core/test/animation/animation_integration_spec.ts @@ -1151,7 +1151,7 @@ function declareTests({useJit}: {useJit: boolean}) { describe('animation output events', () => { it('should fire the associated animation output expression when the animation starts even if no animation is fired', - () => { + fakeAsync(() => { TestBed.overrideComponent(DummyIfCmp, { set: { template: ` @@ -1175,16 +1175,18 @@ function declareTests({useJit}: {useJit: boolean}) { cmp.exp = 'one'; fixture.detectChanges(); + flushMicrotasks(); expect(calls).toEqual(1); expect(isAnimationRunning).toEqual(false); cmp.exp = 'two'; fixture.detectChanges(); + flushMicrotasks(); expect(calls).toEqual(2); expect(isAnimationRunning).toEqual(true); - }); + })); it('should fire the associated animation output expression when the animation ends even if no animation is fired', fakeAsync(() => { @@ -1296,6 +1298,36 @@ function declareTests({useJit}: {useJit: boolean}) { expect(eventData2.totalTime).toEqual(0); })); + it('should successfully update the component view when an animation start callback is fired', + fakeAsync(() => { + TestBed.overrideComponent(DummyIfCmp, { + set: { + template: ` +