My Angular 6 service creates a component dynamically:
buildComponent(viewContainerRef) {
const factory = this.componentFactoryResolver.resolveComponentFactory(MyComponent);
const componentRef = viewContainerRef.createComponent(componentFactory);
...
}
The component I'm creating needs a handle to viewContainerRef in its constructor. How can I pass it from the service while I create the component? Is there a way to perhaps customize the injector that is used when createComponent executes? (hint: I notice that injector is one of the params to createComponent)
I have tried to pass the container to the component on the next line, with something like:
componentRef.instance.viewContainer = viewContainerRef;
This doesn't work for me though because I need the container reference to be available immediately upon construction if possible.
I succeeded by creating a custom injector and providing it as the 3rd param to viewContainerRef.createComponent. Here is my service code:
constructor(
private injector: Injector,
private componentFactoryResolver: ComponentFactoryResolver) {}
buildComponent(viewContainerRef) {
const inj: Injector = this.makeCustomInjector(viewContainerRef);
const factory = this.componentFactoryResolver.resolveComponentFactory(MyComponent);
const componentRef = viewContainerRef.createComponent(componentFactory, undefined, inj);
}
makeCustomInjector(viewContainerRef) {
return Injector.create({
providers: [{provide: ViewContainerRef, useValue: viewContainer}],
parent: this.injector
});
}
Now the MyComponent parent Injector has the viewContainerRef I want. The final step, to be able to inject that view container into the component, is to tell the component to ignore its own injector and take from its parent. This is the MyComponent constructor:
constructor(@SkipSelf() viewContainerRef: ViewContainerRef){}
SkipSelf comes from @angular/core
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