fix(animations): ensure void => * animations are triggered when an expression is omitted

Closes #9327
Closes #9381
This commit is contained in:
Matias Niemelä 2016-06-21 13:56:25 -07:00
parent ed0ade6f34
commit e0b0a594bb
2 changed files with 49 additions and 0 deletions

View File

@ -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(

View File

@ -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],