fix(animations): ensure void => * animations are triggered when an expression is omitted
Closes #9327 Closes #9381
This commit is contained in:
parent
ed0ade6f34
commit
e0b0a594bb
|
@ -562,6 +562,12 @@ class TemplateParseVisitor implements HtmlAstVisitor {
|
||||||
private _parseAnimation(
|
private _parseAnimation(
|
||||||
name: string, expression: string, sourceSpan: ParseSourceSpan,
|
name: string, expression: string, sourceSpan: ParseSourceSpan,
|
||||||
targetMatchableAttrs: string[][], targetAnimationProps: BoundElementPropertyAst[]) {
|
targetMatchableAttrs: string[][], targetAnimationProps: BoundElementPropertyAst[]) {
|
||||||
|
// This will occur when a @trigger is not paired with an expression.
|
||||||
|
// For animations it is valid to not have an expression since */void
|
||||||
|
// states will be applied by angular when the element is attached/detached
|
||||||
|
if (!isPresent(expression) || expression.length == 0) {
|
||||||
|
expression = 'null';
|
||||||
|
}
|
||||||
var ast = this._parseBinding(expression, sourceSpan);
|
var ast = this._parseBinding(expression, sourceSpan);
|
||||||
targetMatchableAttrs.push([name, ast.source]);
|
targetMatchableAttrs.push([name, ast.source]);
|
||||||
targetAnimationProps.push(new BoundElementPropertyAst(
|
targetAnimationProps.push(new BoundElementPropertyAst(
|
||||||
|
|
|
@ -150,6 +150,49 @@ function declareTests({useJit}: {useJit: boolean}) {
|
||||||
});
|
});
|
||||||
})));
|
})));
|
||||||
|
|
||||||
|
it('should animate between * and void and back even when no expression is assigned',
|
||||||
|
inject(
|
||||||
|
[TestComponentBuilder, AnimationDriver],
|
||||||
|
fakeAsync((tcb: TestComponentBuilder, driver: MockAnimationDriver) => {
|
||||||
|
tcb = tcb.overrideTemplate(DummyIfCmp, `
|
||||||
|
<div @myAnimation *ngIf="exp"></div>
|
||||||
|
`);
|
||||||
|
tcb.overrideAnimations(DummyIfCmp, [trigger(
|
||||||
|
'myAnimation',
|
||||||
|
[
|
||||||
|
state('*', style({'opacity': '1'})),
|
||||||
|
state('void', style({'opacity': '0'})),
|
||||||
|
transition('* => *', [animate('500ms')])
|
||||||
|
])])
|
||||||
|
.createAsync(DummyIfCmp)
|
||||||
|
.then((fixture) => {
|
||||||
|
tick();
|
||||||
|
|
||||||
|
var cmp = fixture.debugElement.componentInstance;
|
||||||
|
cmp.exp = true;
|
||||||
|
fixture.detectChanges();
|
||||||
|
flushMicrotasks();
|
||||||
|
|
||||||
|
var result = driver.log.pop();
|
||||||
|
expect(result['duration']).toEqual(500);
|
||||||
|
expect(result['startingStyles']).toEqual({'opacity': '0'});
|
||||||
|
expect(result['keyframeLookup']).toEqual([
|
||||||
|
[0, {'opacity': '0'}], [1, {'opacity': '1'}]
|
||||||
|
]);
|
||||||
|
|
||||||
|
cmp.exp = false;
|
||||||
|
fixture.detectChanges();
|
||||||
|
flushMicrotasks();
|
||||||
|
|
||||||
|
result = driver.log.pop();
|
||||||
|
expect(result['duration']).toEqual(500);
|
||||||
|
expect(result['startingStyles']).toEqual({'opacity': '1'});
|
||||||
|
expect(result['keyframeLookup']).toEqual([
|
||||||
|
[0, {'opacity': '1'}], [1, {'opacity': '0'}]
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
})));
|
||||||
|
|
||||||
it('should combine repeated style steps into a single step',
|
it('should combine repeated style steps into a single step',
|
||||||
inject(
|
inject(
|
||||||
[TestComponentBuilder, AnimationDriver],
|
[TestComponentBuilder, AnimationDriver],
|
||||||
|
|
Loading…
Reference in New Issue