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
This commit is contained in:
Matias Niemelä 2018-05-31 16:52:54 -07:00 committed by Victor Berchet
parent 9367e91402
commit 8db928df9d
2 changed files with 59 additions and 7 deletions

View File

@ -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) {

View File

@ -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: `
<div *ngFor="let item of items" [class]="'class-' + item.value">
<div [@myAnimation]="item.count">
{{ item.value }}
</div>
</div>
`,
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', () => {