angular: Missing a way to retrieve innerHTML of the original element

I think Angular 2 is missing a way to retrieve innerHTML of the original element

<foo>SOME TEXT HERE</foo>

I know I can render the original content with <ng-content>

@Component({
    selector: 'foo',
    template: '<ng-content></ng-content>'
})

However there is no way I can retrieve the original content in constructor, or anywhere in the code. The @Input is only able to access attribute, but not inner HTML. And the ElementRef in constructor is a already modified element. May I know what is the proper way to get inner HTML of the element?

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Reactions: 8
  • Comments: 28 (6 by maintainers)

Most upvoted comments

So one can just inject ElementRef and get a native element from there and do whatever you need. Keep in mind that it is a huge security hole to work with innerHTML.

Assume you have this;

<editor>
 <div *ngFor="var item in items">{{exp}}</div>
</editor>

Here the compiler will get a hold of the content and starts transforming it. Later the editor will use innerHTML and get collisions since both angular and editor are in charge of the same DOM. Presumably the content for the editor comes from a different location, such as database, so the content can not even be there at the time of compilation.

I think the best way to solve this is to have an empty <editor [html]="expr"></editor> component which can do the HTML editing. This is the only way to ensure that there is no DOM contention.

I am sorry, but I will close this as there is not much angular can do to help this use case.

@pkozlowski-opensource I want to make a “editable content” directive, for example:

<div>
  <editable>
    <p>Foo</p>
    <p>Bar</p>
  </editable>
</div>

Whatever is wrapped inside is valid and valuable content to me.

Thanks.

@Component({
    selector: 'editable',
    template: `
    <template [ngIf]="!isEditing">
        {{content}}
    </template>
    <template [ngIf]="isEditing">
        <textarea>{{content}}</textarea>
        <button (click)="save(); $event.stopPropagation()">Save</button>
    </template>
    `
})

This seemed like a valid issue to me. Can we still have this feature? I can’t directly use ng-content because I have to use the text as a value. Here is my use case and workaround for anyone interested:

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

<md-input-container>
  <input disabled readonly mdInput [placeholder]="content.innerText" #textInput>
   ....
</md-input-container>

Hi there I’m trying to create a translate directive for i18n like the following import { Directive, ElementRef } from ‘@angular/core’;

/**
 * TranslateDirective
 * Translates the innerHTML of a DOM element.
 *
 * usage:
 * ```
 * <h1 translate>Edit</h1>
 * ```
 */
@Directive({
    selector: '[translate]',
})
export class TranslateDirective {
    static get parameters() {
        return [[ElementRef]];
    }
    constructor(el) {
        el.nativeElement.innerHTML = translationTable[el.nativeElement.innerHTML]['en'];
    }
}

As I understood this discussion this is not possible. Are there any alternatives?

You need to understand the use case before rejecting it. If innerHTML is not a way to do it then propose another way. If you received formatted HTML from outside, you need to be able to reformat it somewhat to fit angular2 model if you want to include it in a component.