diff --git a/packages/core/test/render3/common_integration_spec.ts b/packages/core/test/render3/common_integration_spec.ts index 7111562ce9..96d33c039e 100644 --- a/packages/core/test/render3/common_integration_spec.ts +++ b/packages/core/test/render3/common_integration_spec.ts @@ -8,11 +8,12 @@ import {NgForOfContext} from '@angular/common'; -import {defineComponent} from '../../src/render3/index'; -import {bind, container, elementEnd, elementProperty, elementStart, interpolation1, interpolation3, listener, text, textBinding, tick} from '../../src/render3/instructions'; +import {getOrCreateNodeInjectorForNode, getOrCreateTemplateRef} from '../../src/render3/di'; +import {AttributeMarker, defineComponent} from '../../src/render3/index'; +import {bind, container, elementEnd, elementProperty, elementStart, interpolation1, interpolation3, listener, load, text, textBinding} from '../../src/render3/instructions'; import {RenderFlags} from '../../src/render3/interfaces/definition'; -import {NgForOf, NgIf} from './common_with_def'; +import {NgForOf, NgIf, NgTemplateOutlet} from './common_with_def'; import {ComponentFixture} from './render_util'; describe('@angular/common integration', () => { @@ -338,4 +339,50 @@ describe('@angular/common integration', () => { }); }); + + describe('NgTemplateOutlet', () => { + + it('should create and remove embedded views', () => { + + class MyApp { + showing = false; + static ngComponentDef = defineComponent({ + type: MyApp, + factory: () => new MyApp(), + selectors: [['my-app']], + /** + * from tpl + * + */ + template: (rf: RenderFlags, myApp: MyApp) => { + if (rf & RenderFlags.Create) { + container(0, (rf1: RenderFlags) => { + if (rf1 & RenderFlags.Create) { + text(0, 'from tpl'); + } + }, undefined, undefined, ['tpl', '']); + container(2, undefined, null, [AttributeMarker.SelectOnly, 'ngTemplateOutlet']); + } + if (rf & RenderFlags.Update) { + const tplRef = getOrCreateTemplateRef(getOrCreateNodeInjectorForNode(load(0))); + elementProperty(2, 'ngTemplateOutlet', bind(myApp.showing ? tplRef : null)); + } + }, + directives: () => [NgTemplateOutlet] + }); + } + + const fixture = new ComponentFixture(MyApp); + expect(fixture.html).toEqual(''); + + fixture.component.showing = true; + fixture.update(); + expect(fixture.html).toEqual('from tpl'); + + fixture.component.showing = false; + fixture.update(); + expect(fixture.html).toEqual(''); + }); + + }); }); diff --git a/packages/core/test/render3/common_with_def.ts b/packages/core/test/render3/common_with_def.ts index 9f3742fd3b..39d1077f0b 100644 --- a/packages/core/test/render3/common_with_def.ts +++ b/packages/core/test/render3/common_with_def.ts @@ -6,14 +6,14 @@ * found in the LICENSE file at https://angular.io/license */ -import {NgForOf as NgForOfDef, NgIf as NgIfDef} from '@angular/common'; -import {InjectFlags, IterableDiffers} from '@angular/core'; +import {NgForOf as NgForOfDef, NgIf as NgIfDef, NgTemplateOutlet as NgTemplateOutletDef} from '@angular/common'; +import {IterableDiffers} from '@angular/core'; -import {defaultIterableDiffers} from '../../src/change_detection/change_detection'; import {DirectiveType, NgOnChangesFeature, defineDirective, directiveInject, injectTemplateRef, injectViewContainerRef} from '../../src/render3/index'; export const NgForOf: DirectiveType> = NgForOfDef as any; export const NgIf: DirectiveType = NgIfDef as any; +export const NgTemplateOutlet: DirectiveType = NgTemplateOutletDef as any; NgForOf.ngDirectiveDef = defineDirective({ type: NgForOfDef, @@ -33,3 +33,13 @@ NgForOf.ngDirectiveDef = defineDirective({ factory: () => new NgIfDef(injectViewContainerRef(), injectTemplateRef()), inputs: {ngIf: 'ngIf', ngIfThen: 'ngIfThen', ngIfElse: 'ngIfElse'} }); + +(NgTemplateOutlet as any).ngDirectiveDef = defineDirective({ + type: NgTemplateOutletDef, + selectors: [['', 'ngTemplateOutlet', '']], + factory: () => new NgTemplateOutletDef(injectViewContainerRef()), + features: [NgOnChangesFeature( + {ngTemplateOutlet: 'ngTemplateOutlet', ngTemplateOutletContext: 'ngTemplateOutletContext'})], + inputs: + {ngTemplateOutlet: 'ngTemplateOutlet', ngTemplateOutletContext: 'ngTemplateOutletContext'} +});