@@ -107,6 +107,33 @@ describe('Portals', () => {
107
107
. toBe ( false , 'Expected content to be removed from outlet on detach.' ) ;
108
108
} ) ;
109
109
110
+ it ( 'should throw when trying to load an element without a parent into a DOM portal' , ( ) => {
111
+ const testAppComponent = fixture . componentInstance ;
112
+ const element = document . createElement ( 'div' ) ;
113
+ const domPortal = new DomPortal ( element ) ;
114
+
115
+ expect ( ( ) => {
116
+ testAppComponent . selectedPortal = domPortal ;
117
+ fixture . detectChanges ( ) ;
118
+ } ) . toThrowError ( 'DOM portal content must be attached to a parent node.' ) ;
119
+ } ) ;
120
+
121
+ it ( 'should not throw when restoring if the outlet element was cleared' , ( ) => {
122
+ const testAppComponent = fixture . componentInstance ;
123
+ const parent = fixture . nativeElement . querySelector ( '.dom-portal-parent' ) ;
124
+ const domPortal = new DomPortal ( testAppComponent . domPortalContent ) ;
125
+
126
+ testAppComponent . selectedPortal = domPortal ;
127
+ fixture . detectChanges ( ) ;
128
+
129
+ parent . innerHTML = '' ;
130
+
131
+ expect ( ( ) => {
132
+ testAppComponent . selectedPortal = undefined ;
133
+ fixture . detectChanges ( ) ;
134
+ } ) . not . toThrow ( ) ;
135
+ } ) ;
136
+
110
137
it ( 'should project template context bindings in the portal' , ( ) => {
111
138
let testAppComponent = fixture . componentInstance ;
112
139
let hostContainer = fixture . nativeElement . querySelector ( '.portal-container' ) ;
@@ -558,6 +585,29 @@ describe('Portals', () => {
558
585
expect ( someDomElement . textContent ! . trim ( ) ) . toBe ( '' ) ;
559
586
} ) ;
560
587
588
+ it ( 'should throw when trying to load an element without a parent into a DOM portal' , ( ) => {
589
+ const fixture = TestBed . createComponent ( PortalTestApp ) ;
590
+ fixture . detectChanges ( ) ;
591
+ const element = document . createElement ( 'div' ) ;
592
+ const portal = new DomPortal ( element ) ;
593
+
594
+ expect ( ( ) => {
595
+ portal . attach ( host ) ;
596
+ fixture . detectChanges ( ) ;
597
+ } ) . toThrowError ( 'DOM portal content must be attached to a parent node.' ) ;
598
+ } ) ;
599
+
600
+ it ( 'should not throw when restoring if the outlet element was cleared' , ( ) => {
601
+ const fixture = TestBed . createComponent ( PortalTestApp ) ;
602
+ fixture . detectChanges ( ) ;
603
+ const portal = new DomPortal ( fixture . componentInstance . domPortalContent ) ;
604
+
605
+ portal . attach ( host ) ;
606
+ host . outletElement . innerHTML = '' ;
607
+
608
+ expect ( ( ) => host . detach ( ) ) . not . toThrow ( ) ;
609
+ } ) ;
610
+
561
611
} ) ;
562
612
} ) ;
563
613
@@ -618,8 +668,10 @@ class ArbitraryViewContainerRefComponent {
618
668
619
669
<ng-template #templateRef let-data> {{fruit}} - {{ data?.status }}!</ng-template>
620
670
621
- <div #domPortalContent>
622
- <p class="dom-portal-inner-content">Hello there</p>
671
+ <div class="dom-portal-parent">
672
+ <div #domPortalContent>
673
+ <p class="dom-portal-inner-content">Hello there</p>
674
+ </div>
623
675
</div>
624
676
` ,
625
677
} )
0 commit comments