diff --git a/modules/@angular/compiler/src/animation/animation_compiler.ts b/modules/@angular/compiler/src/animation/animation_compiler.ts index 8454dd8db2..f80ac3cc3e 100644 --- a/modules/@angular/compiler/src/animation/animation_compiler.ts +++ b/modules/@angular/compiler/src/animation/animation_compiler.ts @@ -486,10 +486,13 @@ class _AnimationTemplatePropertyVisitor implements t.TemplateAstVisitor { t.templateVisitAll(this, ast.children); } + visitEmbeddedTemplate(ast: t.EmbeddedTemplateAst, ctx: any): any { + t.templateVisitAll(this, ast.children); + } + visitEvent(ast: t.BoundEventAst, ctx: any): any {} visitBoundText(ast: t.BoundTextAst, ctx: any): any {} visitText(ast: t.TextAst, ctx: any): any {} - visitEmbeddedTemplate(ast: t.EmbeddedTemplateAst, ctx: any): any {} visitNgContent(ast: t.NgContentAst, ctx: any): any {} visitAttr(ast: t.AttrAst, ctx: any): any {} visitDirective(ast: t.DirectiveAst, ctx: any): any {} diff --git a/modules/@angular/compiler/src/view_compiler/view_binder.ts b/modules/@angular/compiler/src/view_compiler/view_binder.ts index bc7e720de7..403e6cfe51 100644 --- a/modules/@angular/compiler/src/view_compiler/view_binder.ts +++ b/modules/@angular/compiler/src/view_compiler/view_binder.ts @@ -28,7 +28,7 @@ class ViewBinderVisitor implements TemplateAstVisitor { private _nodeIndex: number = 0; private _animationOutputsMap: {[key: string]: AnimationOutput} = {}; - constructor(public view: CompileView, animationOutputs: AnimationOutput[]) { + constructor(public view: CompileView, public animationOutputs: AnimationOutput[]) { animationOutputs.forEach( entry => { this._animationOutputsMap[entry.fullPropertyName] = entry; }); } @@ -108,7 +108,7 @@ class ViewBinderVisitor implements TemplateAstVisitor { var providerInstance = compileElement.instances.get(providerAst.token.reference); bindInjectableDestroyLifecycleCallbacks(providerAst, providerInstance, compileElement); }); - bindView(compileElement.embeddedView, ast.children, []); + bindView(compileElement.embeddedView, ast.children, this.animationOutputs); return null; } diff --git a/modules/@angular/core/test/animation/animation_integration_spec.ts b/modules/@angular/core/test/animation/animation_integration_spec.ts index 5dfdb7eeea..2cc1c70d6d 100644 --- a/modules/@angular/core/test/animation/animation_integration_spec.ts +++ b/modules/@angular/core/test/animation/animation_integration_spec.ts @@ -1266,6 +1266,59 @@ function declareTests({useJit}: {useJit: boolean}) { expect(ifCalls).toEqual(2); expect(loadingCalls).toEqual(2); })); + + + it('should allow animation triggers to trigger on the component when bound to embedded views via ngFor', + fakeAsync(() => { + TestBed.overrideComponent(DummyIfCmp, { + set: { + template: ` +
{{ item }}
+ `, + animations: [trigger('trigger', [transition('* => *', [animate(1000)])])] + } + }); + + const driver = TestBed.get(AnimationDriver) as InnerContentTrackingAnimationDriver; + let fixture = TestBed.createComponent(DummyIfCmp); + var cmp = fixture.debugElement.componentInstance; + + var startCalls = [0, 0, 0, 0, 0]; + var doneCalls = [0, 0, 0, 0, 0]; + cmp.callback = (e: any, index: number, phase: string) => { + (phase == 'start' ? startCalls : doneCalls)[index] = 1; + }; + + cmp.items = [0, 1, 2, 3, 4]; + fixture.detectChanges(); + flushMicrotasks(); + + for (var i = 0; i < cmp.items.length; i++) { + expect(startCalls[i]).toEqual(1); + } + + driver.log[0]['player'].finish(); + driver.log[2]['player'].finish(); + driver.log[4]['player'].finish(); + + expect(doneCalls[0]).toEqual(1); + expect(doneCalls[1]).toEqual(0); + expect(doneCalls[2]).toEqual(1); + expect(doneCalls[3]).toEqual(0); + expect(doneCalls[4]).toEqual(1); + + driver.log[1]['player'].finish(); + driver.log[3]['player'].finish(); + + expect(doneCalls[0]).toEqual(1); + expect(doneCalls[1]).toEqual(1); + expect(doneCalls[2]).toEqual(1); + expect(doneCalls[3]).toEqual(1); + expect(doneCalls[4]).toEqual(1); + })); }); describe('ng directives', () => {