Как использовать SyntaxHighlighter для динамически загружаемых блоков кода с Angular 6?
Я пытаюсь добавить SyntaxHighlighter в свой угловой проект блога. Мои статьи имеют <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>
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 ответа
Решил это. Ответьте здесь, так как это может быть полезно для кого-то еще.
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);
});
SyntaxHighlighter.all()
метод, который выделяет все HTML с <pre>
тэг, вызывается только один раз, т.е. когда страница загружается, потому что вы включили ее в тэг скрипта index.html. Когда этот метод вызывается, он выделит все доступные <pre>
на странице.
Когда вы идете по маршруту, SyntaxHighlighter.all()
должна быть вызвана функция, которая будет выделять новые сгенерированные теги или текст внутри этого тега.
Когда вы обновите страницу, <pre>
теги доступны на странице HTML, когда SyntaxHighlighter.all()
называется, что является причиной, он правильно подсвечивает.
Так что для статей, которые загружаются через связывание, звоните SyntaxHighlighter.all()
в логике, чтобы выделить ваш <pre>
теги.
Вам нужно выбрать правильное событие, где оно должно вызываться в вашем компоненте, а также вам нужно определить переменную в верхней части вашего компонента ниже ваших операторов import, чтобы tslint позволил вам использовать эту переменную в вашем компоненте, т.е. declare var SyntaxHighlighter