Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions goldens/cdk/dialog/index.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import { AfterContentInit } from '@angular/core';
import { AfterViewInit } from '@angular/core';
import * as _angular_cdk_portal from '@angular/cdk/portal';
import { Binding } from '@angular/core';
import { ChangeDetectorRef } from '@angular/core';
import { ComponentRef } from '@angular/core';
import { DoCheck } from '@angular/core';
Expand Down
1 change: 1 addition & 0 deletions goldens/cdk/menu/index.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
```ts

import { AfterContentInit } from '@angular/core';
import { Binding } from '@angular/core';
import { ComponentRef } from '@angular/core';
import { DoCheck } from '@angular/core';
import { ElementRef } from '@angular/core';
Expand Down
1 change: 1 addition & 0 deletions goldens/cdk/overlay/index.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
```ts

import { AfterContentInit } from '@angular/core';
import { Binding } from '@angular/core';
import { ComponentRef } from '@angular/core';
import { DoCheck } from '@angular/core';
import { ElementRef } from '@angular/core';
Expand Down
4 changes: 3 additions & 1 deletion goldens/cdk/portal/index.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
```ts

import { ApplicationRef } from '@angular/core';
import { Binding } from '@angular/core';
import { ComponentRef } from '@angular/core';
import { ElementRef } from '@angular/core';
import { EmbeddedViewRef } from '@angular/core';
Expand Down Expand Up @@ -72,7 +73,8 @@ export type CdkPortalOutletAttachedRef = ComponentRef<any> | EmbeddedViewRef<any

// @public
export class ComponentPortal<T> extends Portal<ComponentRef<T>> {
constructor(component: ComponentType<T>, viewContainerRef?: ViewContainerRef | null, injector?: Injector | null, projectableNodes?: Node[][] | null);
constructor(component: ComponentType<T>, viewContainerRef?: ViewContainerRef | null, injector?: Injector | null, projectableNodes?: Node[][] | null, bindings?: Binding[]);
readonly bindings: Binding[] | null;
component: ComponentType<T>;
injector?: Injector | null;
projectableNodes?: Node[][] | null;
Expand Down
2 changes: 2 additions & 0 deletions src/cdk/portal/dom-portal-outlet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ export class DomPortalOutlet extends BasePortalOutlet {
injector,
ngModuleRef,
projectableNodes: portal.projectableNodes || undefined,
bindings: portal.bindings || undefined,
});

this.setDisposeFn(() => componentRef.destroy());
Expand All @@ -74,6 +75,7 @@ export class DomPortalOutlet extends BasePortalOutlet {
elementInjector,
environmentInjector,
projectableNodes: portal.projectableNodes || undefined,
bindings: portal.bindings || undefined,
});

appRef.attachView(componentRef.hostView);
Expand Down
1 change: 1 addition & 0 deletions src/cdk/portal/portal-directives.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ export class CdkPortalOutlet extends BasePortalOutlet implements OnInit, OnDestr
injector: portal.injector || viewContainerRef.injector,
projectableNodes: portal.projectableNodes || undefined,
ngModuleRef: this._moduleRef || undefined,
bindings: portal.bindings || undefined,
});

// If we're using a view container that's different from the injected one (e.g. when the portal
Expand Down
34 changes: 34 additions & 0 deletions src/cdk/portal/portal.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
ElementRef,
EnvironmentInjector,
Injector,
Input,
QueryList,
TemplateRef,
ViewChild,
Expand All @@ -15,6 +16,7 @@ import {
createComponent,
createEnvironmentInjector,
inject,
inputBinding,
} from '@angular/core';
import {ComponentFixture, TestBed} from '@angular/core/testing';
import {DomPortalOutlet} from './dom-portal-outlet';
Expand Down Expand Up @@ -459,6 +461,25 @@ describe('Portals', () => {

expect(fixture.nativeElement.textContent).toContain('Projectable node');
});

it('should be able to pass bindings to the component', () => {
let flavor = 'pepperoni';
const componentPortal = new ComponentPortal(PizzaMsg, null, null, null, [
inputBinding('flavor', () => flavor),
]);

fixture.componentInstance.selectedPortal = componentPortal;
fixture.changeDetectorRef.markForCheck();
fixture.detectChanges();

const ref = fixture.componentInstance.portalOutlet.attachedRef as ComponentRef<PizzaMsg>;
expect(ref.instance.flavor).toBe('pepperoni');

flavor = 'cheese';
fixture.changeDetectorRef.markForCheck();
fixture.detectChanges();
expect(ref.instance.flavor).toBe('cheese');
});
});

describe('DomPortalOutlet', () => {
Expand Down Expand Up @@ -717,6 +738,17 @@ describe('Portals', () => {
host.attachDomPortal(new DomPortal(fixture.componentInstance.domPortalContent));
expect(host.hasAttached()).toBe(true);
});

it('should be able to pass bindings to the component', () => {
const portal = new ComponentPortal(PizzaMsg, null, null, null, [
inputBinding('flavor', () => 'pepperoni'),
]);

const componentInstance: PizzaMsg = portal.attach(host).instance;
someFixture.changeDetectorRef.markForCheck();
someFixture.detectChanges();
expect(componentInstance.flavor).toBe('pepperoni');
});
});
});

Expand Down Expand Up @@ -744,6 +776,8 @@ class ChocolateInjector {
})
class PizzaMsg {
snack = inject(Chocolate, {optional: true});

@Input() flavor = 'unknown';
}

/**
Expand Down
8 changes: 8 additions & 0 deletions src/cdk/portal/portal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
ComponentRef,
EmbeddedViewRef,
Injector,
Binding,
} from '@angular/core';
import {
throwNullPortalOutletError,
Expand Down Expand Up @@ -99,17 +100,24 @@ export class ComponentPortal<T> extends Portal<ComponentRef<T>> {
*/
projectableNodes?: Node[][] | null;

/**
* Bindings to apply to the created component.
*/
readonly bindings: Binding[] | null;

constructor(
component: ComponentType<T>,
viewContainerRef?: ViewContainerRef | null,
injector?: Injector | null,
projectableNodes?: Node[][] | null,
bindings?: Binding[],
) {
super();
this.component = component;
this.viewContainerRef = viewContainerRef;
this.injector = injector;
this.projectableNodes = projectableNodes;
this.bindings = bindings || null;
}
}

Expand Down
Loading