Как использовать SyntaxHighlighter для динамически загружаемых блоков кода с Angular 6?

Я пытаюсь добавить SyntaxHighlighter в свой проект блога angular. Мои статьи содержат <pre> отформатированных фрагментов кода и загружаются из базы данных. HTML-код этой статьи затем отображается в шаблоне ArticleComponent. Сам этот ArticleComponent загружается при активации определенного маршрута. Но когда я просматриваю этот маршрут и загружается статья, коды в формате <pre> вообще не выделяются. Однако, если я обновляю страницу, выделение работает хорошо. Не уверен, где я ошибаюсь.

index.html

<head>
    <meta charset="utf-8">
    <title>My Blog</title>
    <base href="/">

    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="icon" type="image/x-icon" href="favicon.ico">

    <link rel="stylesheet" href="./assets/css/foundation.css">
    <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.4.1/css/all.css" integrity="sha384-5sAR7xN1Nv6T6+dT2mhtzEpVJvfS3NScPQTrOxhwjIuvcA67KV2R5Jz6kr4abQsz" crossorigin="anonymous">
    <link href="http://alexgorbatchev.com/pub/sh/current/styles/shCore.css" rel="stylesheet" type="text/css" />
    <link href="http://alexgorbatchev.com/pub/sh/current/styles/shThemeDefault.css" rel="stylesheet" type="text/css" />
</head>
<body>
    <app-root></app-root>

    <script type="text/javascript" src="./assets/js/jquery.js"></script>
    <script type="text/javascript" src="./assets/js/what-input.js"></script>
    <script type="text/javascript" src="./assets/js/foundation.js"></script>
    <script>
        $(document).foundation();
    </script>
    <script src="http://alexgorbatchev.com/pub/sh/current/scripts/shCore.js" type="text/javascript"></script>
    <script src="http://alexgorbatchev.com/pub/sh/current/scripts/shBrushBash.js" type="text/javascript" ></script>
    <script type="text/javascript">
        SyntaxHighlighter.defaults['toolbar'] = false;
        SyntaxHighlighter.all()
   </script>
</body>

статья.component.html

<div class="cell">
    <span [innerHTML]="article"></span>
</div>

article.component.ts

export class ArticleComponent implements OnInit {

    public article = '';
    public title = '';

    constructor(private _route: ActivatedRoute, private _articleService: ArticleService) {
    }

    ngOnInit() {
        const articleId: string = this._route.snapshot.paramMap.get('id');

        const allArticles = this._articleService.getArticles();
        const selectedArticleMetaData = allArticles.find(x => x.id === parseInt(articleId, 10));
        this.title = selectedArticleMetaData.title;

        this._articleService
            .getArticleHtml(selectedArticleMetaData.id)
            .subscribe((article: string) => {
                this.article = article;
            });
    }

}

Я проверил элементы HTML DOM и могу убедиться, что статья, которая загружается без обновления, имеет все блоки <pre> в виде необработанного кода. Но когда SyntaxHighlighter действительно работает в случае обновления, все эти теги <pre> преобразуются в элементы div с соответствующими классами стиля.

Похоже, когда статьи загружаются через привязку, SyntaxHighlighter не может обработать теги <pre>. Любая идея, как это исправить? Также есть идеи, почему это работает, когда я обновляю эту страницу? В любом случае статья загружается через привязку.


person kodephreak    schedule 21.10.2018    source источник
comment
Думаю проблема в угловой зоне. Взгляните на этот пакет github.com/MurhafSousli/ngx-highlightjs Я думаю, вы найдете полезным потому что вы можете управлять подсветкой внутри угловой зоны   -  person Kalamarico    schedule 21.10.2018


Ответы (2)


Метод SyntaxHighlighter.all(), который выделяет все html с тегом <pre>, вызывается только один раз, т. е. когда страница загружается, потому что вы включили его в тег скрипта index.html. При вызове этого метода он выделяет все доступные <pre> на странице.

Когда вы переходите к маршруту, необходимо вызвать функцию SyntaxHighlighter.all(), которая выделит новые сгенерированные теги или текст внутри этого тега.

Когда вы обновляете страницу, теги <pre> доступны на странице html, когда вызывается SyntaxHighlighter.all(), что является причиной того, что он правильно выделяется.

Поэтому для статей, которые загружаются через привязку, вызовите SyntaxHighlighter.all() в логике один раз, чтобы выделить теги <pre>.

Вам нужно выбрать правильное событие, где оно должно вызываться в вашем компоненте, а также вам нужно определить переменную в верхней части вашего компонента под вашими операторами импорта, чтобы tslint позволял вам использовать эту переменную в вашем компоненте, т.е. declare var SyntaxHighlighter

person Nabil Shahid    schedule 22.10.2018

Решено. Отвечаю здесь, так как это может быть полезно кому-то другому.

Метод SyntaxHighlighter.all() регистрирует метод Highlight в событии windows.load. Следовательно, этот метод запускается только при загрузке страницы и никогда позже. Это решает загадку того, почему подсветка работала во время обновления страницы, а не при запуске угловой маршрутизации.

Исправление состоит в том, чтобы инициировать событие window.load после загрузки статьи в DOM. Есть лучшие способы сделать это, но вот самый простой способ сделать это. Обновите article.component.ts, включив в него код для запуска события window.load.

this._articleService
    .getArticleHtml(selectedArticleMetaData.id)
    .subscribe((article: string) => {
        this.article = article;
        this.loading = false;

        // trigger window.load event after 500 ms of binding the article property
        setTimeout(() => {
            window.dispatchEvent(new Event('load'));
        }, 500);
    });
person kodephreak    schedule 28.10.2018