highlight.js не работает с Angular 2

Я пытаюсь добавить подсветку синтаксиса в свое приложение, используя highlight.js, но, похоже, он не работает с Angular 2.

Не могли бы вы сообщить мне, что я могу делать неправильно?

Вот Plnkr: https://plnkr.co/edit/G3NFFPGXKyc9mV1a6ufJ?p=preview

Это компонент

import {Component} from 'angular2/core';

@Component({
    selector: "my-app",
    template: `
      Hello!
      <pre>
        <code class="html">
          &lt;html&gt;
            &lt;body&gt;

            &lt;h1&gt;My First Heading&lt;/h1&gt;
            &lt;p&gt;My first paragraph.&lt;/p&gt;

            &lt;/body&gt;
          &lt;/html&gt;
        </code>
      </pre>
    `
})
export class AppComponent{
}

и вот где я добавляю highlight.js, используя cdn:

<!DOCTYPE html>
<html>

<head>
  <!-- IE required polyfills, in this exact order -->
  <script src="https://cdnjs.cloudflare.com/ajax/libs/es6-shim/0.35.0/es6-shim.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.25/system-polyfills.js"></script>
  <script src="https://npmcdn.com/angular2/es6/dev/src/testing/shims_for_IE.js"></script>

  <!-- Angular polyfill required everywhere -->
  <script src="https://code.angularjs.org/2.0.0-beta.13/angular2-polyfills.js"></script>

  <script src="https://code.angularjs.org/tools/system.js"></script>
  <script src="https://code.angularjs.org/tools/typescript.js"></script>
  <script src="https://code.angularjs.org/2.0.0-beta.13/Rx.js"></script>
  <script src="https://code.angularjs.org/2.0.0-beta.13/angular2.dev.js"></script>
  <link rel="stylesheet" href="style.css" />

  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.4.0/styles/solarized-light.min.css">
  <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.4.0/highlight.min.js"></script>
  <script>hljs.initHighlightingOnLoad();</script>

  <script>
      System.config({
        transpiler: 'typescript', 
        typescriptOptions: { emitDecoratorMetadata: true }, 
        packages: {
          'api': {defaultExtension: 'ts'}, 
          'app': {defaultExtension: 'ts'} 
        } 
      });
    System.import('app/main')
          .then(null, console.error.bind(console));
  </script>
</head>

<body>
  <my-app>loading...</my-app>
</body>

</html>

https://highlightjs.org/usage/

5 ответов

Решение

Вы должны явно применить highlightjs на блоке таким образом:

import {Component, ElementRef, ViewChild} from 'angular2/core';

declare var hljs: any;

@Component({
  selector: "my-app",
  template: `
    Hello!
    <pre>
      <code #code class="html">
        &lt;html&gt;
          &lt;body&gt;

          &lt;h1&gt;My First Heading&lt;/h1&gt;
          &lt;p&gt;My first paragraph.&lt;/p&gt;

          &lt;/body&gt;
        &lt;/html&gt;
      </code>
    </pre>
  `
})
export class AppComponent{
  @ViewChild('code')
  codeElement: ElementRef;

  ngAfterViewInit() {
    hljs.highlightBlock(this.codeElement.nativeElement);
  }
}

Смотри этот планкр

Хорошим подходом было бы создать специальную директиву для этого:

@Directive({
  selector: 'code[highlight]'
})
export class HighlightCodeDirective {
  constructor(private eltRef:ElementRef) {
  }

  ngAfterViewInit() {
    hljs.highlightBlock(this.eltRef.nativeElement);
  }
}

и используйте это так:

@Component({
  selector: "my-app",
  template: `
    Hello!
    <pre>
      <code highlight class="html">
        (...)
      </code>
    </pre>
  `,
  directives: [ HighlightCodeDirective ]
})
(...)

Я опубликовал модуль highlight.js для angular, установите его с npm

npm install --save ngx-highlightjs

Он очень прост в использовании, он автоматически загружает скрипт и тему, посмотрите демонстрацию.

Я думаю, что вы должны включить подсветку вручную. Вы можете использовать директиву для этого:

@Directive({
  selector: 'pre'
})
class PreHighlight {
  constructor(refElem: ElementRef) {
    hljs.highlightBlock(refElem.nativeElement);
  }
}

Вот соответствующий plunkr https://plnkr.co/edit/Gf0Y52NIsEmNbbauvL0Y?p=preview

Обновить

Инициализация должна быть перемещена в хук ngAfterViewInit. Смотрите @ Тьерри ответ.

Угловой 12+

Другой способ сделать это - индивидуальное использование highlight.js.

Сначала установите библиотеку

       npm install highlight.js

Добавить файл стилей в angular.json

      "styles": [
   "./node_modules/highlight.js/styles/default.css" // I choose default but you can choose your favorite one.
],

В компоненте вы хотите использовать маркер import highlight.js

      import hljs from 'highlight.js';

...

       constructor(@Inject(DOCUMENT) private document: Document) { }

 ngOnInit(): void {
    setTimeout(() => {
          this.document.querySelectorAll('pre code').forEach((el) => {
            hljs.highlightElement(el);
          });
        }, 500)
  }

Примечание. Если вы получаете данные из API, убедитесь, что ваши данные отображаются на странице, а затем запустите forEach().

На сегодняшний день лучший модуль highlightjs для angular - angular2-highlight-js.

https://www.npmjs.com/package/angular2-highlight-js

npm i angular2-highlight-js
Другие вопросы по тегам