Skip to content

Commit 92af5f1

Browse files
authored
fix(cdk/portal): not marked as attached when going through specific portal methods (#22372)
Fixes that the `DomPortalOutlet.hasAttached` doesn't return the correct information when the portal has been attached through the specific portal methods (e.g. `attachComponentPortal`, `attachTemplatePortal`). Fixes #22370.
1 parent ea5e5e0 commit 92af5f1

File tree

3 files changed

+32
-1
lines changed

3 files changed

+32
-1
lines changed

src/cdk/portal/dom-portal-outlet.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ export class DomPortalOutlet extends BasePortalOutlet {
7171
// At this point the component has been instantiated, so we move it to the location in the DOM
7272
// where we want it to be rendered.
7373
this.outletElement.appendChild(this._getComponentRootNode(componentRef));
74+
this._attachedPortal = portal;
7475

7576
return componentRef;
7677
}
@@ -102,6 +103,8 @@ export class DomPortalOutlet extends BasePortalOutlet {
102103
}
103104
}));
104105

106+
this._attachedPortal = portal;
107+
105108
// TODO(jelbourn): Return locals from view.
106109
return viewRef;
107110
}
@@ -130,6 +133,7 @@ export class DomPortalOutlet extends BasePortalOutlet {
130133

131134
element.parentNode!.insertBefore(anchorNode, element);
132135
this.outletElement.appendChild(element);
136+
this._attachedPortal = portal;
133137

134138
super.setDisposeFn(() => {
135139
// We can't use `replaceWith` here because IE doesn't support it.

src/cdk/portal/portal-directives.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,7 @@ export class CdkPortalOutlet extends BasePortalOutlet implements OnInit, OnDestr
214214
portal.setAttachedHost(this);
215215
element.parentNode!.insertBefore(anchorNode, element);
216216
this._getRootNode().appendChild(element);
217+
this._attachedPortal = portal;
217218

218219
super.setDisposeFn(() => {
219220
if (anchorNode.parentNode) {

src/cdk/portal/portal.spec.ts

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ describe('Portals', () => {
101101
.not.toBe(initialParent, 'Expected portal to be out of the initial parent on attach.');
102102
expect(hostContainer.contains(innerContent))
103103
.toBe(true, 'Expected content to be inside the outlet on attach.');
104+
expect(testAppComponent.portalOutlet.hasAttached()).toBe(true);
104105

105106
testAppComponent.selectedPortal = undefined;
106107
fixture.detectChanges();
@@ -109,6 +110,7 @@ describe('Portals', () => {
109110
.toBe(initialParent, 'Expected portal to be back inside initial parent on detach.');
110111
expect(hostContainer.contains(innerContent))
111112
.toBe(false, 'Expected content to be removed from outlet on detach.');
113+
expect(testAppComponent.portalOutlet.hasAttached()).toBe(false);
112114
});
113115

114116
it('should throw when trying to load an element without a parent into a DOM portal', () => {
@@ -624,6 +626,30 @@ describe('Portals', () => {
624626
expect(() => host.detach()).not.toThrow();
625627
});
626628

629+
it('should set hasAttached when the various portal types are attached', () => {
630+
const fixture = TestBed.createComponent(PortalTestApp);
631+
fixture.detectChanges();
632+
const viewContainerRef = fixture.componentInstance.viewContainerRef;
633+
634+
expect(host.hasAttached()).toBe(false);
635+
636+
host.attachComponentPortal(new ComponentPortal(PizzaMsg, viewContainerRef));
637+
expect(host.hasAttached()).toBe(true);
638+
639+
host.detach();
640+
expect(host.hasAttached()).toBe(false);
641+
642+
host.attachTemplatePortal(
643+
new TemplatePortal(fixture.componentInstance.templateRef, viewContainerRef));
644+
expect(host.hasAttached()).toBe(true);
645+
646+
host.detach();
647+
expect(host.hasAttached()).toBe(false);
648+
649+
host.attachDomPortal(new DomPortal(fixture.componentInstance.domPortalContent));
650+
expect(host.hasAttached()).toBe(true);
651+
});
652+
627653
});
628654
});
629655

@@ -730,7 +756,7 @@ class PortalTestApp {
730756
fruits = ['Apple', 'Pineapple', 'Durian'];
731757
attachedSpy = jasmine.createSpy('attached spy');
732758

733-
constructor(public injector: Injector) { }
759+
constructor(public viewContainerRef: ViewContainerRef, public injector: Injector) { }
734760

735761
get cakePortal() {
736762
return this.portals.first;

0 commit comments

Comments
 (0)