fix(animations): do not retain deleted nodes during an non-removal animation (#17153)
Closes #17086
This commit is contained in:
parent
598fdad089
commit
068133ec85
|
@ -871,24 +871,9 @@ export class TransitionAnimationEngine {
|
|||
const players = queriedElements.get(element);
|
||||
if (players) {
|
||||
optimizeGroupPlayer(players).onDone(fn);
|
||||
} else {
|
||||
let elementPlayers: AnimationPlayer[]|null = null;
|
||||
|
||||
let parent = element;
|
||||
while (parent = parent.parentNode) {
|
||||
const playersForThisElement = this.playersByElement.get(parent);
|
||||
if (playersForThisElement && playersForThisElement.length) {
|
||||
elementPlayers = playersForThisElement;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (elementPlayers) {
|
||||
optimizeGroupPlayer(elementPlayers).onDone(fn);
|
||||
} else {
|
||||
fn();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
rootPlayers.forEach(player => {
|
||||
|
|
|
@ -1127,14 +1127,13 @@ export function main() {
|
|||
expect(count).toEqual(2);
|
||||
});
|
||||
|
||||
it('should always make children wait for the parent animation to finish before any removals occur',
|
||||
it('should allow inner removals to happen when a non removal-based parent animation is set to animate',
|
||||
() => {
|
||||
@Component({
|
||||
selector: 'ani-cmp',
|
||||
template: `
|
||||
<div #parent [@parent]="exp1" class="parent">
|
||||
<div #child1 *ngIf="exp2" class="child1"></div>
|
||||
<div #child2 *ngIf="exp2" class="child2"></div>
|
||||
<div #child *ngIf="exp2" class="child"></div>
|
||||
</div>
|
||||
`,
|
||||
animations: [trigger(
|
||||
|
@ -1148,9 +1147,7 @@ export function main() {
|
|||
|
||||
@ViewChild('parent') public parent: any;
|
||||
|
||||
@ViewChild('child1') public child1Elm: any;
|
||||
|
||||
@ViewChild('child2') public child2Elm: any;
|
||||
@ViewChild('child') public child: any;
|
||||
}
|
||||
|
||||
TestBed.configureTestingModule({declarations: [Cmp]});
|
||||
|
@ -1170,10 +1167,69 @@ export function main() {
|
|||
engine.flush();
|
||||
|
||||
const player = getLog()[0];
|
||||
const p = cmp.parent.nativeElement;
|
||||
const c = cmp.child.nativeElement;
|
||||
|
||||
expect(p.contains(c)).toBeTruthy();
|
||||
|
||||
cmp.exp2 = false;
|
||||
fixture.detectChanges();
|
||||
engine.flush();
|
||||
|
||||
expect(p.contains(c)).toBeFalsy();
|
||||
|
||||
player.finish();
|
||||
|
||||
expect(p.contains(c)).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should make inner removals wait until a parent based removal animation has finished',
|
||||
() => {
|
||||
@Component({
|
||||
selector: 'ani-cmp',
|
||||
template: `
|
||||
<div #parent *ngIf="exp1" @parent class="parent">
|
||||
<div #child1 *ngIf="exp2" class="child1"></div>
|
||||
<div #child2 *ngIf="exp2" class="child2"></div>
|
||||
</div>
|
||||
`,
|
||||
animations: [trigger(
|
||||
'parent',
|
||||
[transition(
|
||||
':leave', [style({opacity: 0}), animate(1000, style({opacity: 1}))])])]
|
||||
})
|
||||
class Cmp {
|
||||
public exp1: any;
|
||||
public exp2: any;
|
||||
|
||||
@ViewChild('parent') public parent: any;
|
||||
|
||||
@ViewChild('child1') public child1Elm: any;
|
||||
|
||||
@ViewChild('child2') public child2Elm: any;
|
||||
}
|
||||
|
||||
TestBed.configureTestingModule({declarations: [Cmp]});
|
||||
|
||||
const engine = TestBed.get(ɵAnimationEngine);
|
||||
const fixture = TestBed.createComponent(Cmp);
|
||||
const cmp = fixture.componentInstance;
|
||||
|
||||
cmp.exp1 = true;
|
||||
cmp.exp2 = true;
|
||||
fixture.detectChanges();
|
||||
engine.flush();
|
||||
resetLog();
|
||||
|
||||
const p = cmp.parent.nativeElement;
|
||||
const c1 = cmp.child1Elm.nativeElement;
|
||||
const c2 = cmp.child2Elm.nativeElement;
|
||||
|
||||
cmp.exp1 = false;
|
||||
cmp.exp2 = false;
|
||||
fixture.detectChanges();
|
||||
engine.flush();
|
||||
|
||||
expect(p.contains(c1)).toBeTruthy();
|
||||
expect(p.contains(c2)).toBeTruthy();
|
||||
|
||||
|
@ -1183,11 +1239,6 @@ export function main() {
|
|||
|
||||
expect(p.contains(c1)).toBeTruthy();
|
||||
expect(p.contains(c2)).toBeTruthy();
|
||||
|
||||
player.finish();
|
||||
|
||||
expect(p.contains(c1)).toBeFalsy();
|
||||
expect(p.contains(c2)).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should substitute in values if the provided state match is an object with values', () => {
|
||||
|
|
Loading…
Reference in New Issue