I am new to Angular, so I am sorry if I screw up the jargon.
I am trying to dynamically use templateURL (html) in my component, the Class function will remain the same but html will change depending on binType
This is my component class source
import { Component, OnInit, Input, Output, EventEmitter, AfterViewInit, ViewContainerRef, ViewChild, Compiler, Injector, NgModule, NgModuleRef } from '@angular/core';
declare var module: {
  id: string;
}
@Component({
  selector: 'app-cart-bin',
  styleUrls: ['./cart-bin.component.css'],  
  template: ` 
      <ng-template #dynamicTemplate></ng-template>
    `
})
export class CartBinComponent implements AfterViewInit, OnInit {
  @ViewChild('dynamicTemplate', {read: ViewContainerRef}) dynamicTemplate;
  public cols = 3;
  public rows = 3;
  @Input() binType = "";
  @Input() toteList = [];
  @Output() callbackMethod = new EventEmitter<string>();
  constructor(private _compiler: Compiler, private _injector: Injector, private _m: NgModuleRef<any>) { }
  ngOnInit() {
    console.log(this.binType);
  }
  ngAfterViewInit() {
    let tmpObj;
    console.log(tmpObj);
    if ((this.binType) == "2") {
      tmpObj = {
        moduleId: module.id,
        templateUrl : './cart-bin.component_02.html'
      };
    } else {
      tmpObj = {
        moduleId: module.id,
        templateUrl : './cart-bin.component_01.html'
      };
    }
    console.log(tmpObj);
    const tmpCmp = Component(tmpObj)(class {});
    const tmpModule = NgModule({declarations: [tmpCmp]})(class {});
    this._compiler.compileModuleAndAllComponentsAsync(tmpModule).then((factories) => {
      const f = factories.componentFactories[0];
      const cmpRef = f.create(this._injector, [], null, this._m);
      cmpRef.instance.name = 'dynamic';
      this.dynamicTemplate.insert(cmpRef.hostView);
    });
}
  getToteBoxClass(toteData){
    ...
  } 
  getToteIcon(toteData){
    ...
  }
  toteSaveClick(toteData){
    ...
  }
}
This is compiling but template is not parsing and getting the following error
ERROR Error: Template parse errors:
Can't bind to 'ngStyle' since it isn't a known property of 'div'.
Html is correct I used it directly as part of @Component TypeDecorator
Besides the fact that using the compiler and creating dynamic components is pretty anti pattern in angular, I believe you can fix your error by adding the CommonModule to your NgModule declaration:
NgModule({imports: [CommonModule], declarations: [tmpCmp]})
Better would be though to use an ngSwitchCase in your template, create two components which inherit from a base component but have different templates, and depending on the binType let it render one or the other component:
template:
<ng-container [ngSwitch]="binType">
  <cart-bin-1 *ngSwitchCase="1"></cart-bin-1>
  <cart-bin-2 *ngSwitchCase="2"></cart-bin-2>
</ng-container>
ts:
export abstract class CartBin {
  // some common cart bin logic here:
}
@Component({
  selector: 'cart-bin-1',
  templateUrl: './cart-bin.component_01.html' 
})
export class CartBin1 extends CartBin {
}
@Component({
  selector: 'cart-bin-2',
  templateUrl: './cart-bin.component_02.html' 
})
export class CartBin2 extends CartBin  {
}
The advantage of using this, is that the AOT bundle will not include the compiler anymore, and therefor making your application smaller and faster. Also, this looks much better :)
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