@@ -11,6 +11,7 @@ import {
1111 Injector ,
1212 ApplicationRef ,
1313} from '@angular/core' ;
14+ import { CommonModule } from '@angular/common' ;
1415import { TemplatePortalDirective , PortalHostDirective , PortalModule } from './portal-directives' ;
1516import { Portal , ComponentPortal } from './portal' ;
1617import { DomPortalHost } from './dom-portal-host' ;
@@ -123,6 +124,28 @@ describe('Portals', () => {
123124 expect ( hostContainer . textContent ) . toContain ( 'Mango' ) ;
124125 } ) ;
125126
127+ it ( 'should load a <ng-template> portal with an inner template' , ( ) => {
128+ let testAppComponent = fixture . debugElement . componentInstance ;
129+
130+ // Detect changes initially so that the component's ViewChildren are resolved.
131+ fixture . detectChanges ( ) ;
132+
133+ // Set the selectedHost to be a TemplatePortal.
134+ testAppComponent . selectedPortal = testAppComponent . portalWithTemplate ;
135+ fixture . detectChanges ( ) ;
136+
137+ // Expect that the content of the attached portal is present.
138+ let hostContainer = fixture . nativeElement . querySelector ( '.portal-container' ) ;
139+ expect ( hostContainer . textContent ) . toContain ( 'Pineapple' ) ;
140+
141+ // When updating the binding value.
142+ testAppComponent . fruits = [ 'Mangosteen' ] ;
143+ fixture . detectChanges ( ) ;
144+
145+ // Expect the new value to be reflected in the rendered output.
146+ expect ( hostContainer . textContent ) . toContain ( 'Mangosteen' ) ;
147+ } ) ;
148+
126149 it ( 'should change the attached portal' , ( ) => {
127150 let testAppComponent = fixture . debugElement . componentInstance ;
128151
@@ -258,6 +281,15 @@ describe('Portals', () => {
258281 expect ( someDomElement . textContent ) . toContain ( 'Cake' ) ;
259282 } ) ;
260283
284+ it ( 'should render a template portal with an inner template' , ( ) => {
285+ let fixture = TestBed . createComponent ( PortalTestApp ) ;
286+ fixture . detectChanges ( ) ;
287+
288+ fixture . componentInstance . portalWithTemplate . attach ( host ) ;
289+
290+ expect ( someDomElement . textContent ) . toContain ( 'Durian' ) ;
291+ } ) ;
292+
261293 it ( 'should attach and detach a template portal with a binding' , ( ) => {
262294 let fixture = TestBed . createComponent ( PortalTestApp ) ;
263295
@@ -384,14 +416,21 @@ class ArbitraryViewContainerRefComponent {
384416 <ng-template cdk-portal>Cake</ng-template>
385417
386418 <div *cdk-portal>Pie</div>
387-
388- <ng-template cdk-portal> {{fruit}} </ng-template>` ,
419+ <ng-template cdk-portal> {{fruit}} </ng-template>
420+
421+ <ng-template cdk-portal>
422+ <ul>
423+ <li *ngFor="let fruitName of fruits"> {{fruitName}} </li>
424+ </ul>
425+ </ng-template>
426+ ` ,
389427} )
390428class PortalTestApp {
391429 @ViewChildren ( TemplatePortalDirective ) portals : QueryList < TemplatePortalDirective > ;
392430 @ViewChild ( PortalHostDirective ) portalHost : PortalHostDirective ;
393431 selectedPortal : Portal < any > ;
394432 fruit : string = 'Banana' ;
433+ fruits = [ 'Apple' , 'Pineapple' , 'Durian' ] ;
395434
396435 constructor ( public injector : Injector ) { }
397436
@@ -406,13 +445,17 @@ class PortalTestApp {
406445 get portalWithBinding ( ) {
407446 return this . portals . toArray ( ) [ 2 ] ;
408447 }
448+
449+ get portalWithTemplate ( ) {
450+ return this . portals . toArray ( ) [ 3 ] ;
451+ }
409452}
410453
411454// Create a real (non-test) NgModule as a workaround for
412455// https://github.com/angular/angular/issues/10760
413456const TEST_COMPONENTS = [ PortalTestApp , ArbitraryViewContainerRefComponent , PizzaMsg ] ;
414457@NgModule ( {
415- imports : [ PortalModule ] ,
458+ imports : [ CommonModule , PortalModule ] ,
416459 exports : TEST_COMPONENTS ,
417460 declarations : TEST_COMPONENTS ,
418461 entryComponents : TEST_COMPONENTS ,
0 commit comments