0

I was thinking about creating small component in Angular that will do what <ng-include> is doing in angularJS.

First, I must give component a template or templateUrl for compiling? What if it something I will know only in run time?

@Component({
  selector: 'my-template',
  // templateUrl: '',    //won't render, must give it something?
})
export class MyTemplate {

 @Input() templateURL: string;

  constructor() {
    console.log("template component was created!");
  }

}

I want to create instance of that component in code and give its templateUrl. Something like that:

 var factory = this.resolver.resolveComponentFactory(MyTemplate);
factory.templateUrl =    // Is that possible?

Can it be done somehow? the templateUrl is something that will come from @input How in code I create instance of component and give it its input?

AngularOne
  • 2,760
  • 6
  • 32
  • 46

1 Answers1

0

I think you should use dynamic component loading to do that.

We might create HtmlOutlet directive that will create component dynamicallу with desired templateUrl:

@Directive({
  selector: 'html-outlet' 
})
export class HtmlOutlet {
  @Input() html: string;

  constructor(private vcRef: ViewContainerRef, private compiler: Compiler) {}

  ngOnChanges() {
    const html = this.html;
    if (!html) return;

    @Component({
      selector: 'dynamic-comp',
      templateUrl: html
    })
    class DynamicHtmlComponent  { };

    @NgModule({
      imports: [CommonModule],
      declarations: [DynamicHtmlComponent]
    })
    class DynamicHtmlModule {}

    this.compiler.compileModuleAndAllComponentsAsync(DynamicHtmlModule)
      .then(factory => {
        const compFactory = factory.componentFactories
               .find(x => x.componentType === DynamicHtmlComponent);
        const cmpRef = this.vcRef.createComponent(compFactory, 0);
        cmpRef.instance.prop = 'test';
        cmpRef.instance.outputChange.subscribe(()=>...);
    });
  }
}

And then use it like:

<html-outlet [html]="article?.html">

Where html is path to article.html

Suneet Bansal
  • 2,664
  • 1
  • 14
  • 18