4

I'm creating a layout with D3, and I'm trying to dynamically insert Angular components into the structure.

I've managed to get components dynamically created using a ViewContainerRef injected into the parent component:

constructor(vcRef: ViewContainerRef...

I could also have got a ViewContainerRef from a html element in the template like this:

@ViewChild('htmlElementINeed', { read: ViewContainerRef }) targetConterinRef;

However, as I'm dynamically creating the html elements wher I need my components using D3, I cannot use the injected ViewContainerRef, or get a ViewContainerRef from the template using @ViewChild.

The angular documentation lists these as the two ways to access it::

To access a ViewContainerRef of an Element, you can either place a Directive injected with ViewContainerRef on the Element, or you obtain it via a ViewChild query.

Is there any way to manually create a ViewContainerRef, or get one for an element not defined in the template? Is it a restriction of Angular that I can only dynamically create components on a html element that is already in template at compile time?

Joe
  • 6,773
  • 2
  • 47
  • 81
  • Only if you create and compile a component at runtime http://stackoverflow.com/questions/34784778/equivalent-of-compile-in-angular-2/37044960#37044960. `ViewContainerRef` need to be known when a component is compiles. With AoT, this is when the application is built for deployment. – Günter Zöchbauer May 15 '17 at 11:32
  • Any idea how to do it with JIT? I've found lots of examples of how to compile components that are dynamic - but that's not the issue, it's the *inserting* them dynamically where i have the problem. – Joe May 15 '17 at 12:26
  • I'd have to create a component with D3, parse it into Angular, to compile it into a component. I might try to see if I can *move* it within the DOM to where it needs to be. – Joe May 15 '17 at 12:31
  • You can create a component with the D3 markup statically added to a dynamically compiled component. There you can add template variables to the D3 elements and then query them using `@ViewChild('xxx')` to get `ViewContainerRef` where you can add components dynamically. – Günter Zöchbauer May 15 '17 at 12:40
  • @GünterZöchbauer what do you mean with template variables? – titusfx Jul 26 '17 at 08:55
  • `
    ` allows you to query by string (as you do in your question. You need to create and compile a component at runtime if you need this in dynamically created HTML. Angular only processes anything Angular-related in HTML when a component is compiled.
    – Günter Zöchbauer Jul 26 '17 at 08:57
  • @Joe If I understood correctly, I had more or less the same problem with tables. And for creating "dynamic viewContainerRef" my solution was create a dynamic component that has dynamic viewContainerRef. In your case your biggest Component should be created dynamically ( a plain string ) add the viewContainerRef and then when compiled yours ViewContainerRef will be dynamic. – titusfx Jul 26 '17 at 08:59
  • @Joe also you can use now ngTemplateOutlet here is a https://stackoverflow.com/questions/44564914/multiple-transclusion-using-ngfor-in-angular2 – titusfx Jul 26 '17 at 09:08

0 Answers0