1

I was able to create a dynamic component after one week of research. I came up with this:

import { Component, Input, ComponentRef,ViewChild,ViewContainerRef, ComponentFactoryResolver}   from '@angular/core';
import { AfterViewInit,OnInit,OnDestroy}          from '@angular/core';
import { OnChanges,SimpleChange,ComponentFactory} from '@angular/core';
import { TestModule }    from './test.module';
import { TestComponent } from './test.component';

@Component({
  selector: 'dynamic-detail',
  template: `<div> <div #dynamicContentPlaceHolder></div> </div> `,
})

export class DynamicDetail implements AfterViewInit, OnChanges, OnDestroy, OnInit {

  @ViewChild('dynamicContentPlaceHolder', {
      read: ViewContainerRef
  })
  protected dynamicComponentTarget: ViewContainerRef;
  // this will be reference to dynamic content - to be able to destroy it
  protected componentRef: ComponentRef < IHaveDynamicData > ;

  // until ngAfterViewInit, we cannot start (firstly) to process dynamic stuff
  protected wasViewInitialized = false;


  // wee need Dynamic component builder
  constructor(
    protected typeBuilder: DynamicTypeBuilder, 
    private componentFactoryResolver: ComponentFactoryResolver
  ) {}

  /** Get a Factory and create a component */

  protected refreshContent() {

    if (this.componentRef) {
        this.componentRef.destroy();
    }

    const childComponent =this.componentFactoryResolver.resolveComponentFactory(TestComponent); 

    this.componentRef = this.dynamicComponentTarget.createComponent(childComponent);

    ...
  }
  ...
}

For my test component i have

import { Component, Input, OnInit } from '@angular/core';

@Component({
  selector: 'dynamic-component',
  template: 'i am dynamic',
})
export class TestComponent implements OnInit {
  @Input()  public entity: any;

  constructor(){}

  public ngOnInit(): void {}
}

and module

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { BrowserModule } from '@angular/platform-browser';

import { TestComponent } from './test.component';

@NgModule({
  imports: [ CommonModule, BrowserModule ],
  declarations: [ TestComponent ],
  entryComponents: [ TestComponent ],
  providers: [ ]
})
export class TestModule { }

It works fine. My question is, how can i pass dynamic template to the component?

Like for example in TestComponent

@Component({
  selector: 'dynamic-component',
  template: $dynamicTemplateVariable,
})

and in my main component

this.template = "<div>i am generated form another source</div>"
this.componentRef = this.dynamicComponentTarget.createComponent(childComponent, this.template);

The template can be gotten from any source, from and api too.

Shashank Vivek
  • 16,888
  • 8
  • 62
  • 104
  • I believe what you’re looking for is the NgTemplateOutlet. Check this example https://alligator.io/angular/reusable-components-ngtemplateoutlet/ – Hugo Noro Mar 17 '18 at 19:31
  • Have you looked at this post? https://stackoverflow.com/questions/38888008/how-can-i-use-create-dynamic-template-to-compile-dynamic-component-with-angular – Daniel W Strimpel Mar 17 '18 at 19:37
  • @DanielWStrimpel I have. I'm not creating my modules dynamically(i tried, but not working for --prod). Its not helpful in my case – Medunoye Laxus Gbenga Mar 17 '18 at 19:41
  • 1
    Did you look at the answer with 30 up votes? They create a dynamic component using the template string given, which is what I believe you were asking for. The concern about any solution would be that it wouldn't work in AOT mode tho since the template compiler would not be shipped (regardless of how you get the dynamic component template to work) – Daniel W Strimpel Mar 17 '18 at 20:44
  • Although looking at the documentation for the `Compiler` class that is used in that one answer makes me think it would be possible if you used that. https://angular.io/api/core/Compiler – Daniel W Strimpel Mar 17 '18 at 20:50

0 Answers0