Skip to content

Commit 139b622

Browse files
refactor(core): clarify comments on enter animation queuing (#64550)
This just updates the comments and adds some tests to verify some of the queuing behavior for enter animations. PR Close #64550
1 parent b055141 commit 139b622

File tree

2 files changed

+63
-4
lines changed

2 files changed

+63
-4
lines changed

packages/core/src/render3/instructions/animation.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,11 @@ export function ɵɵanimateEnter(value: string | Function): typeof ɵɵanimateEn
7777

7878
initializeAnimationQueueScheduler(lView[INJECTOR]);
7979

80-
// TODO(thePunderWoman): it's unclear why we need to queue animations here, but without this,
81-
// animating through host bindings fails
80+
// We have to queue here due to the animation instruction being invoked after the element
81+
// instruction. The DOM node has to exist before we can queue an animation. Any node that
82+
// is not inside of control flow needs to get queued here. For nodes inside of control
83+
// flow, those are queued in node_manipulation.ts and are deduped by a Set in the animation
84+
// queue.
8285
queueEnterAnimations(lView[INJECTOR], getLViewEnterAnimations(lView));
8386

8487
return ɵɵanimateEnter; // For chaining
@@ -202,8 +205,11 @@ export function ɵɵanimateEnterListener(value: AnimationFunction): typeof ɵɵa
202205

203206
initializeAnimationQueueScheduler(lView[INJECTOR]);
204207

205-
// TODO(thePunderWoman): it's unclear why we need to queue animations here, but without this,
206-
// animating through host bindings fails
208+
// We have to queue here due to the animation instruction being invoked after the element
209+
// instruction. The DOM node has to exist before we can queue an animation. Any node that
210+
// is not inside of control flow needs to get queued here. For nodes inside of control
211+
// flow, those are queued in node_manipulation.ts and are deduped by a Set in the animation
212+
// queue.
207213
queueEnterAnimations(lView[INJECTOR], getLViewEnterAnimations(lView));
208214

209215
return ɵɵanimateEnterListener;

packages/core/test/acceptance/animation_spec.ts

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -886,6 +886,59 @@ describe('Animation', () => {
886886
expect(cmp.el.nativeElement.outerHTML).toContain('class="slide-in"');
887887
}));
888888

889+
it('should call animation function on entry when animation is specified with no control flow', fakeAsync(() => {
890+
@Component({
891+
selector: 'test-cmp',
892+
styles: styles,
893+
template: '<div><p (animate.enter)="slideIn($event)">I should slide in</p></div>',
894+
encapsulation: ViewEncapsulation.None,
895+
})
896+
class TestComponent {
897+
count = signal(0);
898+
slideIn(event: AnimationCallbackEvent) {
899+
this.count.update((c) => (c += 1));
900+
event.animationComplete();
901+
}
902+
}
903+
TestBed.configureTestingModule({animationsEnabled: true});
904+
905+
const fixture = TestBed.createComponent(TestComponent);
906+
const cmp = fixture.componentInstance;
907+
fixture.detectChanges();
908+
tickAnimationFrames(1);
909+
expect(cmp.count()).toBe(1);
910+
}));
911+
912+
it('should call animation function only once on entry when animation is specified with control flow', fakeAsync(() => {
913+
@Component({
914+
selector: 'test-cmp',
915+
styles: styles,
916+
template:
917+
'<div>@if(show()) {<p (animate.enter)="slideIn($event)">I should slide in</p>}</div>',
918+
encapsulation: ViewEncapsulation.None,
919+
})
920+
class TestComponent {
921+
count = signal(0);
922+
show = signal(false);
923+
slideIn(event: AnimationCallbackEvent) {
924+
this.count.update((c) => (c += 1));
925+
event.animationComplete();
926+
}
927+
}
928+
TestBed.configureTestingModule({animationsEnabled: true});
929+
930+
const fixture = TestBed.createComponent(TestComponent);
931+
const cmp = fixture.componentInstance;
932+
fixture.detectChanges();
933+
tickAnimationFrames(1);
934+
expect(cmp.count()).toBe(0);
935+
936+
cmp.show.update((s) => !s);
937+
fixture.detectChanges();
938+
tickAnimationFrames(1);
939+
expect(cmp.count()).toBe(1);
940+
}));
941+
889942
it('should apply classes on entry when animation is specified', fakeAsync(() => {
890943
@Component({
891944
selector: 'test-cmp',

0 commit comments

Comments
 (0)