From 56b3f1703e57c86eed4a24feb40b2fc6284ad6f1 Mon Sep 17 00:00:00 2001 From: Pawel Kozlowski Date: Mon, 16 Jul 2018 14:21:54 +0200 Subject: [PATCH] fix(ivy): invoke lifecycle hooks of directives placed on ng-template (#24899) PR Close #24899 --- packages/core/src/render3/instructions.ts | 6 +- packages/core/test/render3/lifecycle_spec.ts | 64 +++++++++++++++++++- 2 files changed, 63 insertions(+), 7 deletions(-) diff --git a/packages/core/src/render3/instructions.ts b/packages/core/src/render3/instructions.ts index a226cbb499..187ada2015 100644 --- a/packages/core/src/render3/instructions.ts +++ b/packages/core/src/render3/instructions.ts @@ -1727,10 +1727,8 @@ export function container( isParent = false; ngDevMode && assertNodeType(previousOrParentNode, TNodeType.Container); - if (queries) { - // check if a given container node matches - queries.addNode(node); - } + queries && queries.addNode(node); // check if a given container node matches + queueLifecycleHooks(node.tNode.flags, tView); } /** diff --git a/packages/core/test/render3/lifecycle_spec.ts b/packages/core/test/render3/lifecycle_spec.ts index 4bb3656fb2..48c72a4d3f 100644 --- a/packages/core/test/render3/lifecycle_spec.ts +++ b/packages/core/test/render3/lifecycle_spec.ts @@ -6,11 +6,13 @@ * found in the LICENSE file at https://angular.io/license */ -import {SimpleChanges} from '../../src/core'; -import {ComponentTemplate, LifecycleHooksFeature, NgOnChangesFeature, defineComponent, defineDirective} from '../../src/render3/index'; +import {OnDestroy, SimpleChanges} from '../../src/core'; +import {AttributeMarker, ComponentTemplate, LifecycleHooksFeature, NgOnChangesFeature, defineComponent, defineDirective} from '../../src/render3/index'; import {bind, container, containerRefreshEnd, containerRefreshStart, elementEnd, elementProperty, elementStart, embeddedViewEnd, embeddedViewStart, listener, markDirty, projection, projectionDef, store, text} from '../../src/render3/instructions'; import {RenderFlags} from '../../src/render3/interfaces/definition'; -import {containerEl, renderComponent, renderToHtml, requestAnimationFrame} from './render_util'; + +import {NgIf} from './common_with_def'; +import {ComponentFixture, containerEl, createComponent, renderComponent, renderToHtml, requestAnimationFrame} from './render_util'; describe('lifecycles', () => { @@ -2525,4 +2527,60 @@ describe('lifecycles', () => { }); + describe('non-regression', () => { + + it('should call lifecycle hooks for directives active on ', () => { + let destroyed = false; + + class OnDestroyDirective implements OnDestroy { + ngOnDestroy() { destroyed = true; } + + static ngDirectiveDef = defineDirective({ + type: OnDestroyDirective, + selectors: [['', 'onDestroyDirective', '']], + factory: () => new OnDestroyDirective() + }); + } + + + function conditionTpl(rf: RenderFlags, ctx: Cmpt) { + if (rf & RenderFlags.Create) { + container(0, cmptTpl, null, [AttributeMarker.SelectOnly, 'onDestroyDirective']); + } + } + + /** + * + * + * + */ + function cmptTpl(rf: RenderFlags, cmpt: Cmpt) { + if (rf & RenderFlags.Create) { + container(0, conditionTpl, null, [AttributeMarker.SelectOnly, 'ngIf']); + } + if (rf & RenderFlags.Update) { + elementProperty(0, 'ngIf', bind(cmpt.showing)); + } + } + + class Cmpt { + showing = true; + static ngComponentDef = defineComponent({ + type: Cmpt, + factory: () => new Cmpt(), + selectors: [['cmpt']], + template: cmptTpl, + directives: [NgIf, OnDestroyDirective] + }); + } + + const fixture = new ComponentFixture(Cmpt); + expect(destroyed).toBeFalsy(); + + fixture.component.showing = false; + fixture.update(); + expect(destroyed).toBeTruthy(); + }); + }); + });