0

I'm building a CMS and I'm trying to re-render Prism.js when the body of the article changes to display the syntax highlignting in the preview.

The template:

<textarea 
    [(ngModel)]="article.body" 
    (ngModelChange)="onBodyChange($event)" 
    formControlName="body" type="text" name="body"> 
</textarea>

The Component ( The ngAfterViewChecked() works but the onBodyChange() doesn't ):

onBodyChange() {
    this.highlightService.highlightAll();
    this.highlighted = true;
}

ngAfterViewChecked() {
  if (this.article && !this.highlighted) {
    this.highlightService.highlightAll();
    this.highlighted = true;
  }
}

Some people suggest to re-render Prism.js using the following method but I'm a bit confused on how to implement it:

Prism.highlightElement(precode);

This is the service:

import { Injectable, Inject } from '@angular/core';
import { PLATFORM_ID } from '@angular/core';
import { isPlatformBrowser } from '@angular/common';

import 'clipboard';

import 'prismjs';
import 'prismjs/plugins/toolbar/prism-toolbar';
import 'prismjs/plugins/copy-to-clipboard/prism-copy-to-clipboard';
import 'prismjs/components/prism-css';
import 'prismjs/components/prism-javascript';
import 'prismjs/components/prism-markup';
import 'prismjs/components/prism-typescript';
import 'prismjs/components/prism-scss';

declare var Prism: any;

@Injectable()
export class HighlightService {

  constructor(@Inject(PLATFORM_ID) private platformId: Object) { }

  highlightAll() {
    if (isPlatformBrowser(this.platformId)) {
      Prism.highlightAll();
    }
  }
}
  • When your onBodyChange() method is called, the preview hasn't yet been updated. And you prevent the ngAfterViewChecked from highlighting by setting `this.highlighted` to true. My guess (but you provided no example to play with, so it's just a guess) is that you should do the exact reverse: not highlighting, setting `this.highlighted` to false, so that the next call to ngAfterViewChecked re-hightlights. Also: you shouldn't have formControlName on your textarea. This is for reactive forms. You have a template-dreven form. – JB Nizet Jan 20 '18 at 10:46
  • Anyway, for better help, post a complete minimal example as a plunkr or stackblitz. – JB Nizet Jan 20 '18 at 10:47
  • Thank you very much @JBNizet . Your comment helped me solved this. –  Jan 20 '18 at 11:49

1 Answers1

0

I solved it following the suggestion in the comment above. I just had to set this.highlighted to true:

ngAfterViewChecked() {
  if (this.article && !this.highlighted) {
    this.highlightService.highlightAll();
    this.highlighted = true;
  }
}

No (ngModelChange) needed in the form:

<textarea 
    [(ngModel)]="article.body" 
    formControlName="body" type="text" name="body"> 
</textarea>

Thanks