1

I'm fairly new to Angular, so bear with me.

I want to dynamically insert HTML into a page and have it treated as an Angular template containing components/directives/etc.

As a contrived example, say I have my main app component HTML:

<div #pageContent></div>

And I have my app component TS:

import { Component, ElementRef, ViewChild, OnInit } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {

  @ViewChild('pageContent') pageContent: ElementRef;

  ngOnInit() {
    this.pageContent.nativeElement.innerHTML = `
      <h1>Test HTML</h1>
      <a routerLink="/test">Test</a>
      <p>Regular paragraph text</p>
    `;
  }
}

This is just an example, but in my actual app the HTML will be loaded by a service at run time, not hard-coded as above, so the HTML to be inserted will not be known at compile time.

This example renders a page with plain HTML, and the anchor tag does not function as an Angular RouterLink component.

I understand that Angular intentionally does not ship with the compiler in order to save on download size, so I can't just say "parse this HTML" and have it do all the leg work for me.

And I understand that there are risks associated with inserting HTML dynamically, but let's assume that I have a good reason to do it anyway and I have other protections in place to prevent malicious HTML from being inserted.

I'm wondering if, for example, I could manually look for any anchor tags in the incoming HTML, manually create a RouterLink instance and replace it in the rendered HTML in place of the old, non-functioning anchor tag.

I want to be able to do the same with custom components as well, not just RouterLink.

I'm completely open to suggestion on how to achieve this - the above was just my best guess at how it might work.

The only examples I can find of this kind of thing are for Angular 1.x, but I'm using Angular 8.

Thanks

Sam Williams
  • 565
  • 4
  • 11
  • 1
    Possible duplicate of [Angular2: Insert a dynamic component as child of a container in the DOM](https://stackoverflow.com/questions/38093727/angular2-insert-a-dynamic-component-as-child-of-a-container-in-the-dom) – joyBlanks Sep 08 '19 at 20:43
  • This is not a duplicate of the suggested question. The key difference is that the suggested question knows in advance the content of the template, but I am trying to replace the content of the template at run time and _then_ insert the dynamic component. – Sam Williams Sep 10 '19 at 13:23
  • @SamWilliams even though you insert the html to element, you will loose all angular binding, for example your routerLink won't work – Reza Sep 10 '19 at 13:37
  • Please refer life cycle hooks for angular: https://angular.io/guide/lifecycle-hooks. Also try to create ctor for component and try injecting html there instead ngOnInit(), i believe it may works though i never tried it. – Harshad Vekariya Sep 10 '19 at 13:40
  • @Reza I know that - that's my question - how do I get it to apply the binding after I dynamically insert HTML into the page? – Sam Williams Sep 10 '19 at 16:41
  • @HarshadVekariya I tried it in the constructor as well, but it still doesn't work. – Sam Williams Sep 10 '19 at 16:42
  • Perhaps another way to phrase this question might be "How do I change a component's template at run time?" I think that's effectively what I'm trying to do, but my example above is doing it by inserting HTML into the template rather than replacing the template completely. – Sam Williams Sep 10 '19 at 16:43

0 Answers0