如何在Angular 6的动态加载的代码块上使用SyntaxHighlighter?

时间:2018-10-21 14:56:11

标签: javascript angular syntaxhighlighter

我正在尝试将SyntaxHighlighter添加到我的有角度的博客项目中。我的文章具有<pre>格式的代码段,并已从数据库中加载。然后,本文HTML将显示在ArticleComponent模板中。当触发特定路由时,将加载Article Article本身。 但是当我浏览到此路线并加载了一篇文章时,<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>

article.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>标签。任何想法如何解决这个问题?还知道我刷新此页面时为何起作用吗?无论哪种情况,文章都是通过绑定加载的。

2 个答案:

答案 0 :(得分:0)

使用SyntaxHighlighter.all()标签突出显示所有html的<pre>方法仅被调用一次,即,在加载页面时,因为您将其包含在index.html的脚本标签中。调用此方法时,它将突出显示页面上所有可用的<pre>

去一条路线时,需要调用SyntaxHighlighter.all()函数,该函数将突出显示新生成的标签或该标签内的文本。

刷新页面时,调用<pre>时,页面html上有SyntaxHighlighter.all()标签,这是其正确突出显示的原因。

因此,对于通过绑定加载的文章,请在逻辑上调用SyntaxHighlighter.all()以突出显示<pre>标签。

您需要选择正确的事件,该事件应该在您的组件中调用,并且还需要在import语句下方的组件顶部定义一个变量,以便tslint应该允许您在组件中使用该变量即declare var SyntaxHighlighter

答案 1 :(得分:0)

已解决。在此处回答该问题可能会对其他人有所帮助。

SyntaxHighlighter.all()方法将一个 Highlight 方法注册到windows.load事件。因此,此方法仅在页面加载时触发,以后再也不会触发。这解决了为什么在页面刷新期间而不是在触发角度路由时高亮起作用的谜团。

解决方法是在将文章加载到DOM后触发window.load事件。有更好的方法可以做到这一点,但这是最直接的方法。更新 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);
    });