How to dynamically create an instance of a component with input / output from a service and implement it separately in the DOM?

When creating dynamic components in Angular 2, I found that this process requires a ViewContainerRef to add a newly created component to the DOM.

And by passing @Input and @Output these dynamically created components, I found the answer in the second link above and here .

However, if I had to create a service called shape.service that contains functions that return various form components with some @Input for example bgColor , I don’t know how this service will create a component without specifying the DOM location and how the container component gets this returned the component (probably its type will be ComponentRef ) from the service and injects it into the specification of the DOM container component.

For example, a service contains a method:

 getCircle(bgColor:string): ComponentRef<Circle> { let circleFactory = componentFactoryResolver.resolveComponentFactory(CircleComponent); let circleCompRef = this.viewContainerRef.createComponent(circleFactory); circleCompRef.instance.bgColor = bgColor; return circleCompRef; } 

The first question this.viewContainerRef here, how can I make this.viewContainerRef point to anything at this time? The reason I'm importing ViewContainerRef is to create the component dynamically.

Second question: after the container component receives the input componentRef specific from the service, how will it embed it in its DOM?

UPDATE: I think my question above was not specific enough. I am in a situation where:

  1. The parent component calls the service and gets componentRef / s,
  2. Creates an object that includes componentRef / s along with some other data and stores the created objects in an array
  3. @Input it to your children like @Input ,
  4. And let each child element inject componentRef into its DOM and use the rest of the data in the object in a different way.

This means that the component that calls the service has no idea where these componentRef will be inserted. In short, I need independent component objects that can be inserted anywhere and anytime.

I have read the rumTimeCompiler solution several times, but I don’t quite understand how it works. It seems like there is too much work here compared to creating components using viewContainerRef. I will delve deeper into this if I cannot find another solution ...

+5
source share
1 answer

Perhaps this plunker will help you: https://plnkr.co/edit/iTG7Ysjuv7oiDozuXwj6?p=preview

As far as I know, you will need a ViewContainerRef inside your service. But the component that calls your service can add it as a parameter, for example:

(just a service .. see plunker for a full working example)

 import { Injectable, ViewContainerRef, ReflectiveInjector, ComponentFactoryResolver, ComponentRef } from '@angular/core'; import { HelloComponent, HelloModel } from './hello.component'; @Injectable() export class DynamicCompService { constructor (private componentFactoryResolver: ComponentFactoryResolver) { } public createHelloComp (vCref: ViewContainerRef, modelInput: HelloModel): ComponentRef { let factory = this.componentFactoryResolver.resolveComponentFactory(HelloComponent); // vCref is needed cause of that injector.. let injector = ReflectiveInjector.fromResolvedProviders([], vCref.parentInjector); // create component without adding it directly to the DOM let comp = factory.create(injector); // add inputs first !! otherwise component/template crashes .. comp.instance.model = modelInput; // all inputs set? add it to the DOM .. vCref.insert(comp.hostView); return comp; } } 
+6
source

All Articles