6

I'm trying to create a custom directive to replace the inner text of my custom directive. I can't seem to access the inner text content to apply some logic.

Here's the code:

import { Directive, ElementRef, Renderer2, ViewContainerRef } from '@angular/core';

@Directive({
  selector: 'text-transformer'
})
export class TextTransformerDirective {
  constructor(
    private elem: ElementRef) {
      // need access to inner text before setting new text
      // elem.nativeElement.outerHTML, innerHTML, outerText, innerText are all empty at this point
      elem.nativeElement.outerHTML = '<span>My new Text</span>';
  }
}

Usage:

<text-transformer>Some text</text-transformer>

I would like to inspect the text inside the tag, in this case, "Some text". I can't seem to access it inside the directive.

Should I use component instead?

Will
  • 1,718
  • 3
  • 15
  • 23

1 Answers1

10

You're attempting to use a directive like most would use a component.

However, to transform text, it is a directive you want. Just change your selector.

Check out this plunk:

https://plnkr.co/edit/C3SR92TVN1x5bgSazWNW?p=preview

import {Directive, ElementRef, OnInit} from '@angular/core'

@Directive({
  selector: '[text-transformer]'
})
export class TextTransformerDirective implements ngOnInit {

    constructor(
    private elem: ElementRef) {
      // need access to inner text before setting new text
      // elem.nativeElement.outerHTML, innerHTML, outerText, innerText are all empty at this point

    }

  ngOnInit() {
    console.log(this.elem.nativeElement.innerText);
    this.elem.nativeElement.innerText += ' !!My new Text!!';
    console.log(this.elem.nativeElement.innerText) 
  }

}

Then use that directive from any other component like so:

<h1 text-transformer>This text will be changed</h1>

And for reference: https://angular.io/guide/attribute-directives

Pezetter
  • 2,783
  • 2
  • 22
  • 40
  • I ran your plunker and I still don't have access to the original text. Try changing your child component to: elem.nativeElement.outerHTML += ':My new Text'; and you'll see what I mean. – Will Mar 20 '18 at 18:47
  • Oh my bad. Just change it to innerText. There are a bunch of ways to accomplish this. Console log the elem and play with all the properties you want. – Pezetter Mar 20 '18 at 18:50
  • OP can change innerText, he can't get current text – yurzui Mar 20 '18 at 18:59
  • That += adds it to the current text, therefore, you have the current text..? – Pezetter Mar 20 '18 at 19:01
  • Moved to ngOnInit, so the element can be put into the DOM before we start updating it in the controller constructor. Then you have access to innerText. – Pezetter Mar 20 '18 at 19:07
  • Yeah? that and put the logic in ngOnInit. You could just answer the question yourself ya know? – Pezetter Mar 20 '18 at 19:16
  • Thank you very much @Everett, the ngOnInit was the answer. – Will Mar 20 '18 at 22:21
  • 1
    Great! This just answers the question instead of advising a component or whatever. As I came here to find an answer to the question as I need a directive. Awesome, thanks. – Mike de Klerk May 21 '20 at 12:52