fix(animations): should not invoke disabled child animations (#37724)

Currently child animation will be triggered by `animateChild()` despite it has been disabled.
These changes add some logic to prevent that unexpected behavior.

PR Close #37724

PR Close #37724
This commit is contained in:
zuckjet
2020-06-25 12:23:58 +08:00
committed by Alex Rickabaugh
parent 6c05c3fd2d
commit bab7ed3541
2 changed files with 69 additions and 5 deletions
@@ -1034,7 +1034,14 @@ export class TransitionAnimationEngine {
// instead stretch the first keyframe gap until the animation starts. This is
// important in order to prevent extra initialization styles from being
// required by the user for the animation.
instruction.timelines.forEach(tl => tl.stretchStartingKeyframe = true);
const timelines: AnimationTimelineInstruction[] = [];
instruction.timelines.forEach(tl => {
tl.stretchStartingKeyframe = true;
if (!this.disabledNodes.has(tl.element)) {
timelines.push(tl);
}
});
instruction.timelines = timelines;
subTimelines.append(element, instruction.timelines);
@@ -3309,14 +3309,14 @@ describe('animation query tests', function() {
})
class Cmp {
exp: any = '';
disableExp = false;
disabledExp = false;
}
TestBed.configureTestingModule({declarations: [Cmp]});
const fixture = TestBed.createComponent(Cmp);
const cmp = fixture.componentInstance;
cmp.disableExp = true;
cmp.disabledExp = true;
fixture.detectChanges();
resetLog();
@@ -3363,14 +3363,14 @@ describe('animation query tests', function() {
})
class Cmp {
exp: any = '';
disableExp = false;
disabledExp = false;
}
TestBed.configureTestingModule({declarations: [Cmp]});
const fixture = TestBed.createComponent(Cmp);
const cmp = fixture.componentInstance;
cmp.disableExp = true;
cmp.disabledExp = true;
fixture.detectChanges();
resetLog();
@@ -3386,6 +3386,63 @@ describe('animation query tests', function() {
expect(p2.duration).toEqual(1000);
expect(p2.element.classList.contains('parent')).toBeTrue();
});
it('should disable the animation for the given element regardless of existing parent element animation queries or child element animation queries',
() => {
@Component({
selector: 'some-cmp',
template: `
<div class="parent" [@parentAnimation]="exp">
<div class="child" [@.disabled]="disabledExp" [@childAnimation]="exp">
<div class="grand-child" [@grandChildAnimation]="exp"></div>
</div>
</div>
`,
animations: [
trigger(
'parentAnimation',
[
transition(
'* => go',
[query('@*', animateChild()), animate(1500, style({opacity: 0}))]),
]),
trigger(
'childAnimation',
[
transition('* => go', [animate(1000, style({opacity: 0}))]),
]),
trigger(
'grandChildAnimation',
[
transition('* => go', [animate(500, style({opacity: 0}))]),
]),
]
})
class Cmp {
exp: any = '';
disabledExp = false;
}
TestBed.configureTestingModule({declarations: [Cmp]});
const fixture = TestBed.createComponent(Cmp);
const cmp = fixture.componentInstance;
cmp.disabledExp = true;
fixture.detectChanges();
resetLog();
cmp.exp = 'go';
fixture.detectChanges();
const players = getLog();
expect(players.length).toEqual(2);
const [p1, p2] = players;
expect(p1.duration).toEqual(500);
expect(p1.element.classList.contains('grand-child')).toBeTrue();
expect(p2.duration).toEqual(1500);
expect(p2.element.classList.contains('parent')).toBeTrue();
});
});
});
});