I would like to use the new Portal from material CDK to inject dynamic content in multiple part of a form.
I have a complex form structure and the goal is to have a form that specify multiple place where sub components could (or not) inject templates.
Maybe the CDK Portal is not the best solution for this?
I tried something but I am sure it is not the way of doing: https://stackblitz.com/edit/angular-yuz1kg
I tried also with new ComponentPortal(MyPortalComponent)
but how can we set Inputs on it ? Usually is something like componentRef.component.instance.myInput
You can create a custom injector and inject it to the component portal you create.
createInjector(dataToPass): PortalInjector { const injectorTokens = new WeakMap(); injectorTokens.set(CONTAINER_DATA, dataToPass); return new PortalInjector(this._injector, injectorTokens); }
CONTAINER_DATA
is a custom injector (InjectorToken
) created by -
export const CONTAINER_DATA = new InjectionToken<{}>('CONTAINER_DATA');
To consume created injector, use -
let containerPortal = new ComponentPortal(ComponentToPort, null, this.createInjector({ data1, data2 })); overlay.attach(containerPortal);
overlay
is an instance of OverlayRef
(Which is Portal Outlet)
Inside ComponentToPort
, you will need to inject the created injector -
@Inject(CONTAINER_DATA) public componentData: any
If you are using Angular 10+ and following Awadhoot's answer, PortalInjector is now deprecated so instead of:
new PortalInjector(this.injector, new WeakMap([[SOME_TOKEN, data]]))
You now have:
Injector.create({ parent: this.injector, providers: [ { provide: SOME_TOKEN, useValue: data } ] })
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With