Render string input of ng-content directly as HTML

Viewed 1651

Is it possible for a component to receive content passed to it between opening and closing tags and assign the input directly to innerHTML inside the receiving template?

I have a string input like this:

public content: string =
  '<div class="row">' +
  '  <div class="col">' +
  '    <h1>Friendly greetings!</h1>' +
  '    <p>' +
  '      This is my homepage..' +
  '    </p>' +
  '  </div>' +
  '</div>';

And put it in my component like this:

<app-content>{{ content }}</app-content>

Inside app-content I can use ng-content in the template to project the input content. Since the input is a string I only get to see a string, the HTML elements it describes are not rendered.

I tried to inject the ElementRef and access the text node via this.elementRef.nativeElement.textContent, but the content must have been rendered first to access it that way.

Of course, I could hide the content ng-content produces like this:

<div style="display: none">
  <ng-content></ng-content>
</div>

And then get the textContent in a variable (e.g. content) and set it like this:

<div [outerHTML]="content"></div>

But that seems hacky to me.

StackBlitz project: get-input-of-ng-content-directly

Am I missing something?

I want to do something like this in the template: <div [outerHTML]="incoming ng-content stuff"></div>

Or at least inject the content in the components constructor and set it to a variable, but without rendering the content first just to hide it.

1 Answers

I'd say you have two options:

1.) @Input() field that receives your content above and then renders the content as innerHTML like you mentioned. So something like

<app-content [content]="content"></app-content>

And then you can render you content Input like you have above with the <div [innerHTML]=...

2.) Or you can use <ng-content> inside of your <app-content> HTML file and then just do something like this:

<app-content>
  <div [innerHTML]="content"></div>
</app-content>

But this second option probably assumes <app-content> is not the root element from which your Angular app is boostrapped.

Related