From 8db928df9de7b08695d4dbfbe2542cdccb680e0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matias=20Niemel=C3=A4?= Date: Thu, 31 May 2018 16:52:54 -0700 Subject: [PATCH] fix(animations): retain trigger-state for nodes that are moved around (#24238) This patch ensures that if a list of nodes (that contain animation triggers) are moved around then they will retain their trigger-value state when animated again at a later point. PR Close #24238 --- .../src/render/transition_animation_engine.ts | 7 --- .../animation/animation_integration_spec.ts | 59 +++++++++++++++++++ 2 files changed, 59 insertions(+), 7 deletions(-) diff --git a/packages/animations/browser/src/render/transition_animation_engine.ts b/packages/animations/browser/src/render/transition_animation_engine.ts index 205f6ecbba..4864388f53 100644 --- a/packages/animations/browser/src/render/transition_animation_engine.ts +++ b/packages/animations/browser/src/render/transition_animation_engine.ts @@ -104,7 +104,6 @@ export class StateValue { export const VOID_VALUE = 'void'; export const DEFAULT_STATE_VALUE = new StateValue(VOID_VALUE); -export const DELETED_STATE_VALUE = new StateValue('DELETED'); export class AnimationTransitionNamespace { public players: TransitionAnimationPlayer[] = []; @@ -208,8 +207,6 @@ export class AnimationTransitionNamespace { if (!fromState) { fromState = DEFAULT_STATE_VALUE; - } else if (fromState === DELETED_STATE_VALUE) { - return player; } const isRemoval = toState.value === VOID_VALUE; @@ -773,10 +770,6 @@ export class TransitionAnimationEngine { } }); } - const stateMap = this.statesByElement.get(element); - if (stateMap) { - Object.keys(stateMap).forEach(triggerName => stateMap[triggerName] = DELETED_STATE_VALUE); - } } finishActiveQueriedAnimationOnElement(element: any) { diff --git a/packages/core/test/animation/animation_integration_spec.ts b/packages/core/test/animation/animation_integration_spec.ts index a1dcb50b60..f94bca7d0c 100644 --- a/packages/core/test/animation/animation_integration_spec.ts +++ b/packages/core/test/animation/animation_integration_spec.ts @@ -2379,6 +2379,65 @@ const DEFAULT_COMPONENT_ID = '1'; }); }); }); + + it('should animate nodes properly when they have been re-ordered', () => { + @Component({ + selector: 'if-cmp', + template: ` +
+
+ {{ item.value }} +
+
+ `, + animations: [ + trigger( + 'myAnimation', + [ + state('0', style({opacity: 0})), state('1', style({opacity: 0.4})), + state('2', style({opacity: 0.8})), transition('* => 1, * => 2', [animate(1000)]) + ]), + ] + }) + class Cmp { + items = [ + {value: '1', count: 0}, + {value: '2', count: 0}, + {value: '3', count: 0}, + {value: '4', count: 0}, + {value: '5', count: 0}, + ]; + + reOrder() { + this.items = [ + this.items[4], + this.items[1], + this.items[3], + this.items[0], + this.items[2], + ]; + } + } + + TestBed.configureTestingModule({declarations: [Cmp]}); + const fixture = TestBed.createComponent(Cmp); + const cmp = fixture.componentInstance; + const one = cmp.items[0]; + const two = cmp.items[1]; + one.count++; + fixture.detectChanges(); + + cmp.reOrder(); + fixture.detectChanges(); + resetLog(); + + one.count++; + two.count++; + fixture.detectChanges(); + + const players = getLog(); + expect(players.length).toEqual(2); + }); }); describe('animation listeners', () => {