It's possible evaluate template from string in a variable?. I need place the string in the component instead of the expression, e.g.
template: "<div>{{ template_string }}</div>"
template_string contains: <b>{{ name }}</b> 
and all should be evaluated to <div><b>My Name</b></div> 
but I see <div>{{ template_string }}</div>
I need something like {{ template_string | eval }} or something else to evaluate the content of the variable on current context.
It's possible? I need something to use this approach because template_string can be changed when the component is used. 
Edit1:
Angular Version: 4.0.3
E.g.
@Component({
  selector: 'product-item',
  template: `
    <div class="product">{{ template }}</div>`,
})
export class ProductItemComponent {
  @Input() name: string;
  @Input() price: number = 0;
  @Input() template: string = `{{ name }} <b>{{ price | currency }}</b>`;
}
Usage:
<product-item [name]="product.name" [price]="product.price"></product-item>
Expected: Product Name USD3.00
Output:     {{ name }} <b>{{ price | currency }}</b>
You can create your own directive that will do it:
compile.directive.ts
@Directive({
  selector: '[compile]'
})
export class CompileDirective implements OnChanges {
  @Input() compile: string;
  @Input() compileContext: any;
  compRef: ComponentRef<any>;
  constructor(private vcRef: ViewContainerRef, private compiler: Compiler) {}
  ngOnChanges() {
    if(!this.compile) {
      if(this.compRef) {
        this.updateProperties();
        return;
      }
      throw Error('You forgot to provide template');
    }
    this.vcRef.clear();
    this.compRef = null;
    const component = this.createDynamicComponent(this.compile);
    const module = this.createDynamicModule(component);
    this.compiler.compileModuleAndAllComponentsAsync(module)
      .then((moduleWithFactories: ModuleWithComponentFactories<any>) => {
        let compFactory = moduleWithFactories.componentFactories.find(x => x.componentType === component);
        this.compRef = this.vcRef.createComponent(compFactory);
        this.updateProperties();
      })
      .catch(error => {
        console.log(error);
      });
  }
  updateProperties() {
    for(var prop in this.compileContext) {
      this.compRef.instance[prop] = this.compileContext[prop];
    }
  }
  private createDynamicComponent (template:string) {
    @Component({
      selector: 'custom-dynamic-component',
      template: template,
    })
    class CustomDynamicComponent {}
    return CustomDynamicComponent;
  }
  private createDynamicModule (component: Type<any>) {
    @NgModule({
      // You might need other modules, providers, etc...
      // Note that whatever components you want to be able
      // to render dynamically must be known to this module
      imports: [CommonModule],
      declarations: [component]
    })
    class DynamicModule {}
    return DynamicModule;
  }
}
Usage:
@Component({
  selector: 'product-item',
  template: `
    <div class="product">
      <ng-container *compile="template; context: this"></ng-container>
    </div>
  `,
})
export class ProductItemComponent {
  @Input() name: string;
  @Input() price: number = 0;
  @Input() template: string = `{{ name }} <b>{{ price | currency }}</b>`;
}
Plunker Example
See also
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