A user can provide optional ResolvedReflectiveProvider[]
to the constructor of ComponentPortal
, this is a good way to provide data for dialogs.
The component type in ComponentPortal
use the injector of the ViewContainerRef
.
Dialog must use a service to get data from the application.
Before creating the component in DomPortalHost
create a child injector with the bindings:
/** DomPortalHost **/
/** Attach the given ComponentPortal to DOM element using the ComponentResolver. */
attachComponentPortal(portal: ComponentPortal): Promise<ComponentRef<any>> {
if (portal.viewContainerRef == null) {
throw new MdComponentPortalAttachedToDomWithoutOriginError();
}
return this._componentResolver.resolveComponent(portal.component).then(componentFactory => {
const childInjector = ReflectiveInjector
.fromResolvedProviders(portal.bindings, portal.viewContainerRef.parentInjector);
let ref = portal.viewContainerRef.createComponent(
componentFactory, portal.viewContainerRef.length, childInjector);
let hostView = <EmbeddedViewRef<any>> ref.hostView;
this._hostDomElement.appendChild(hostView.rootNodes[0]);
this.setDisposeFn(() => ref.destroy());
return ref;
});
}
/** ComponentPortal **/
/**
* A `ComponentPortal` is a portal that instantiates some Component upon attachment.
*/
export class ComponentPortal extends Portal<ComponentRef<any>> {
/** The type of the component that will be instantiated for attachment. */
public component: Type;
public bindings: ResolvedReflectiveProvider[];
/**
* [Optional] 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 PortalHost.
* The origin necessary when the host is outside of the Angular application context.
*/
public viewContainerRef: ViewContainerRef;
constructor(component: Type, viewContainerRef: ViewContainerRef = null,
bindings: ResolvedReflectiveProvider[] = null) {
super();
this.component = component;
this.viewContainerRef = viewContainerRef;
this.bindings = Array.isArray(bindings) ? bindings : [];
}
}
My PR #761 lets you pass an Injector
instance to let you configure what's available to the component. Beyond that, the thinking is that you can set stuff directly to the component instance once you've created it.
How injector helps to provide inputs of the component?
I understand how I can provide data with custom injection token. But I will have to obtain this data by DI (using created token), but not inputs of the component.
What I am missing? Does injector store information about inputs too?
With that thoughts in mind (custom injection token) this question comes to the mind: how providing data via injection token (through custom injector + DI in dynamically created component) differs from passing data via service (like author used initially)?
UPD:
Ok, possible workaround are:
All of this ways are not looking good solutions for simple providing inputs for dynamically created components using CDK.
FYI @jelbourn
This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.
Read more about our automatic conversation locking policy.
_This action has been performed automatically by a bot._
Most helpful comment
How injector helps to provide inputs of the component?
I understand how I can provide data with custom injection token. But I will have to obtain this data by DI (using created token), but not inputs of the component.
What I am missing? Does injector store information about inputs too?
With that thoughts in mind (custom injection token) this question comes to the mind: how providing data via injection token (through custom injector + DI in dynamically created component) differs from passing data via service (like author used initially)?
UPD:
Ok, possible workaround are:
All of this ways are not looking good solutions for simple providing inputs for dynamically created components using CDK.
FYI @jelbourn