Johni
Johni

Reputation: 2959

Angular: detect when content html is changed in Component/Directive

I have a directive getting html from a REST endpoint and binding it to a div element via [innerHTML]. After this html is rendered I want to call a function which is globally available to mess with this content.

So what I tried was to create a directive which implements AfterView init and added it to my div element:

<div specialContent [innerHtml]="entry.body">
@Directive({
  selector: '[specialContent]'
})
export class SpecialContentDirective implements AfterViewInit {

  constructor(
    private el: ElementRef
  ) {}

  ngAfterViewInit(): void {
    globalObject.applyTo(
      this.el.nativeElement.querySelectorAll('.target')
    );
  }

}

This kind of works but only if the current component which renders the context is freshly loaded. After reloading the content without unloading the component ngAfterViewInit obviously isn't triggered again.

So what's the correct way to do such thing in Angular?

Upvotes: 1

Views: 6920

Answers (3)

TechNinja
TechNinja

Reputation: 1

You can use Lifecycle hook to detect changes using a life cycle hook called "ngOnChanges" either in your component or directive. Here is the sample code from official website of angular.

ngOnChanges(changes: SimpleChanges) {
  for (let propName in changes) {
    let chng = changes[propName];
    let cur  = JSON.stringify(chng.currentValue);
    let prev = JSON.stringify(chng.previousValue);
    this.changeLog.push(`${propName}: currentValue = ${cur}, previousValue = ${prev}`);
  }
}

SimpleChanges object here provides you previous and new value.

For further Information, you can read official documentation https://angular.io/guide/lifecycle-hooks

Upvotes: 0

noririco
noririco

Reputation: 795

It is not so clear what you try to achieve with applyTo method.

Why not try to use the directive with an Input ?

in HTML

<div [specialContent]="entry.body">

in directive

@Directive({
  selector: '[specialContent]'
})
export class SpecialContentDirective implements OnChanges {
  @Input('specialContent') myContent: string;
  constructor(
    private el: ElementRef
  ) {}

  ngOnChanges(changes: SimpleChanges){
    if(changes.myContent) {
      this.el.nativeElement.innerHTML = myContent;

      globalObject.applyTo(
       this.el.nativeElement.querySelectorAll('.target')
      );
    }
  }

}

Upvotes: 1

Sam
Sam

Reputation: 1851

Assuming you have a service that is using angular's http client to perform the api call. If not you probably should use this approach.

Call the Api and subscribe to the response, then fire a function once it is completed.

Subscribe has 3 stages, next, error, complete.

this._service.api().subscribe(
    data => {
        this.data = data
    }, error => {
    //handle error
    }, () => {
    //Fire Function to mess with content
    }
)

You could also mess with the data before assigning it to your variable (this is probably the better way of doing it) though not sure exactly what you want to achieve.

Upvotes: 0

Related Questions