1

How do I compile a component defined by a string and render it in my template?

I tried using DomSanitizer:

this.sanitizer.bypassSecurityTrustHtml(parsedLinksString);

But that doesn't properly bind the click event handler onButtonClick().

Desired Functionality

@Component({
    selector: 'app-sample-component',
    templateUrl: './sample-component.component.html',
    styleUrls: ['./sample-component.component.scss']
})
export class SampleComponent {

  buildMessage() {
    // How do I parse this string and render so that it responds to events?
    const myOutput = '<button (click)="onButtonClick()';
  }

  onButtonClick() {
    console.log('Handler for Dynamic Button');
  }

}

Community
  • 1
  • 1
  • are you using the `innerHTML` attribute on the parent DOM element to the rendered string? from [here](https://stackoverflow.com/a/48914307/5927442) – LostJon Sep 24 '19 at 20:45
  • This strikes me as an [XY Problem](https://meta.stackexchange.com/a/66378/193656). People may be able to better assist you if you ask about what outcome or functionality you are trying to obtain. What is the reason for trying to create a button like this via an HTML string? – Chris Yungmann Sep 24 '19 at 22:10
  • Yes, I tried using the innerHtml attribute and render it, however (click) events does not work as it's pure HTML and does not understand Angular bindings. – Fabricio Frontarolli Sep 25 '19 at 21:08
  • How would you develop the following component? A Notification Component, that is connects to a store, and any component can call an action and displays notifications. However, these notification texts may contain a call to action link (like, click here for more). This link is a dynamic content and also have to bind to a method/event in an Angular class – Fabricio Frontarolli Sep 25 '19 at 21:09
  • If only want a button, check this [SO](https://stackoverflow.com/questions/71479471/execute-angular-innerhtml-as-normal-angular-code/71480844#71480844) – Eliseo Mar 24 '22 at 21:09

2 Answers2

1

The Angular security model is designed such that HTML added to [innerHTML]="myOutput" is not processed (i.e. scripts are not executed and events are not triggered).

Angular options to compile HTML include:

Add HTML to a Component Template

In your example, the HTML would go in sample-component.component.html. To dynamically include or exclude HTML in a template, use structural directives such as *ngIf and *ngFor.

Create a Dynamic Component to load at Runtime

See Dynamic Component Loader

Stackblitz Demo

Community
  • 1
  • 1
Christopher Peisert
  • 21,862
  • 3
  • 86
  • 117
0

TLDR: https://stackblitz.com/edit/angular-ivy-86uxvs?file=src/app/app.component.html

I did same question and the solution was here made by @cris hamilton.

elciospy
  • 260
  • 4
  • 11