3

i am trying to bind/render html content with innerHTML but not able to render {{...}} in angular.

code as below:

<div [innerHtml]="TestString"></div>

test = " HTML Content ";
TestString = "<div>This is test code, i am trying to bind/render {{ test }} code with angular..,</div>";

result

This is test code, i am trying to bind/render {{ test }} code with angular..,

not binding/render test variable value....

1
  • You can also concatenate strings in your .ts file TestString = '<div>This is test code, i am trying to bind/render' + this.test +' code with angular..,</div>' Commented Mar 6, 2020 at 12:04

1 Answer 1

7

Try this way:

test = " HTML Content ";
TestString = `<div>This is test code, i am trying to bind/render ${this.test} code with angular..,</div>`

https://stackblitz.com/edit/angular-ckxsp8?file=src/app/app.component.ts

If you want to evaluate template from string inside a component, You can create your own directive that will do it:

compile.directive.ts

import {
  Compiler, NgModule, Component, Input, ComponentRef, Directive, 
  ModuleWithComponentFactories, OnChanges, Type,
  ViewContainerRef
} from '@angular/core';
import { CommonModule } from '@angular/common';

@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: 'my-app',
  templateUrl: './app.component.html',
})
export class AppComponent {

  name = 'Product Name :'
  price = '3'
  template: string = `{{ name }} <b>{{ price }}$</b>`;
}

HTML:

<div class="product">
  <ng-container *compile="template; context: this"></ng-container>
</div>

DEMO: https://stackblitz.com/edit/angular-eipbup?file=src%2Fapp%2Fapp.component.html

Sign up to request clarification or add additional context in comments.

10 Comments

thanks and above code is working fine but i am trying something else as below:
what exactly do you need?
want to iterate object
Hey @SunilPune could you solve this? or what was your plan b for this problem?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.