diff --git a/src/cdk/portal/dom-portal-outlet.ts b/src/cdk/portal/dom-portal-outlet.ts
index 168793b1a288..aa9255d469e5 100644
--- a/src/cdk/portal/dom-portal-outlet.ts
+++ b/src/cdk/portal/dom-portal-outlet.ts
@@ -74,6 +74,7 @@ export class DomPortalOutlet extends BasePortalOutlet {
componentFactory,
portal.viewContainerRef.length,
portal.injector || portal.viewContainerRef.injector,
+ portal.projectableNodes || undefined,
);
this.setDisposeFn(() => componentRef.destroy());
diff --git a/src/cdk/portal/portal-directives.ts b/src/cdk/portal/portal-directives.ts
index 0986f3b051cb..452249f5bb1b 100644
--- a/src/cdk/portal/portal-directives.ts
+++ b/src/cdk/portal/portal-directives.ts
@@ -133,8 +133,7 @@ export class CdkPortalOutlet extends BasePortalOutlet implements OnInit, OnDestr
ngOnDestroy() {
super.dispose();
- this._attachedPortal = null;
- this._attachedRef = null;
+ this._attachedRef = this._attachedPortal = null;
}
/**
@@ -157,6 +156,7 @@ export class CdkPortalOutlet extends BasePortalOutlet implements OnInit, OnDestr
componentFactory,
viewContainerRef.length,
portal.injector || viewContainerRef.injector,
+ portal.projectableNodes || undefined,
);
// If we're using a view container that's different from the injected one (e.g. when the portal
diff --git a/src/cdk/portal/portal.spec.ts b/src/cdk/portal/portal.spec.ts
index feaf8eed93be..6ab823fa86ea 100644
--- a/src/cdk/portal/portal.spec.ts
+++ b/src/cdk/portal/portal.spec.ts
@@ -450,6 +450,19 @@ describe('Portals', () => {
expect(hostContainer.textContent).toContain('Pizza');
});
+
+ it('should be able to pass projectable nodes to portal', () => {
+ // Set the selectedHost to be a ComponentPortal.
+ const testAppComponent = fixture.componentInstance;
+ const componentPortal = new ComponentPortal(PizzaMsg, undefined, undefined, undefined, [
+ [document.createTextNode('Projectable node')],
+ ]);
+
+ testAppComponent.selectedPortal = componentPortal;
+ fixture.detectChanges();
+
+ expect(fixture.nativeElement.textContent).toContain('Projectable node');
+ });
});
describe('DomPortalOutlet', () => {
@@ -728,7 +741,7 @@ class ChocolateInjector {
/** Simple component for testing ComponentPortal. */
@Component({
selector: 'pizza-msg',
- template: '
Pizza
{{snack}}
',
+ template: 'Pizza
{{snack}}
',
})
class PizzaMsg {
constructor(@Optional() public snack: Chocolate) {}
diff --git a/src/cdk/portal/portal.ts b/src/cdk/portal/portal.ts
index 2a79759c8942..0c44c960727b 100644
--- a/src/cdk/portal/portal.ts
+++ b/src/cdk/portal/portal.ts
@@ -86,13 +86,13 @@ export class ComponentPortal extends Portal> {
component: ComponentType;
/**
- * [Optional] Where the attached component should live in Angular's *logical* component tree.
+ * Where the attached component should live in Angular's *logical* component tree.
* This is different from where the component *renders*, which is determined by the PortalOutlet.
* The origin is necessary when the host is outside of the Angular application context.
*/
viewContainerRef?: ViewContainerRef | null;
- /** [Optional] Injector used for the instantiation of the component. */
+ /** Injector used for the instantiation of the component. */
injector?: Injector | null;
/**
@@ -101,17 +101,24 @@ export class ComponentPortal extends Portal> {
*/
componentFactoryResolver?: ComponentFactoryResolver | null;
+ /**
+ * List of DOM nodes that should be projected through `` of the attached component.
+ */
+ projectableNodes?: Node[][] | null;
+
constructor(
component: ComponentType,
viewContainerRef?: ViewContainerRef | null,
injector?: Injector | null,
componentFactoryResolver?: ComponentFactoryResolver | null,
+ projectableNodes?: Node[][] | null,
) {
super();
this.component = component;
this.viewContainerRef = viewContainerRef;
this.injector = injector;
this.componentFactoryResolver = componentFactoryResolver;
+ this.projectableNodes = projectableNodes;
}
}
diff --git a/tools/public_api_guard/cdk/portal.md b/tools/public_api_guard/cdk/portal.md
index 34eaa4f26f08..c26a22d7a736 100644
--- a/tools/public_api_guard/cdk/portal.md
+++ b/tools/public_api_guard/cdk/portal.md
@@ -78,10 +78,11 @@ export type CdkPortalOutletAttachedRef = ComponentRef | EmbeddedViewRef extends Portal> {
- constructor(component: ComponentType, viewContainerRef?: ViewContainerRef | null, injector?: Injector | null, componentFactoryResolver?: ComponentFactoryResolver | null);
+ constructor(component: ComponentType, viewContainerRef?: ViewContainerRef | null, injector?: Injector | null, componentFactoryResolver?: ComponentFactoryResolver | null, projectableNodes?: Node[][] | null);
component: ComponentType;
componentFactoryResolver?: ComponentFactoryResolver | null;
injector?: Injector | null;
+ projectableNodes?: Node[][] | null;
viewContainerRef?: ViewContainerRef | null;
}