在 Angular 2 中使用 Highlight JS
Using Highlight JS in Angular 2
我正在尝试在我的 Angular 2 应用程序中使用 Highlight JS,当代码块不是静态信息时,我在弄清楚如何使用它时遇到了一些麻烦。我的意思是,代码字符串来自服务器通过 http get 调用。
所以,如果我有这个:
export class WorkstationComponent implements OnInit {
private submission = new Submission();
private criteria = new Array<ExerciseCriteria>();
private codeString:string = `
/* HelloWorld.java
*/
public class HelloWorld
{
public static void main(String[] args) {
System.out.println("Hello World!");
}
}`;
constructor(private _router:Router, private submissionService:SubmissionService,
private activatedRoute:ActivatedRoute){}
@ViewChild('code') codeElement: ElementRef;
ngOnInit(){
this.activatedRoute.params
// (+) converts string 'id' to a number
.switchMap((params: Params) => this.submissionService.getSubmission(+params['id']))
.subscribe(data => this.success(data),
error => this.fail(error));
}
success(data:any){
this.submission = data;
this.criteria = data.criteria;
hljs.highlightBlock(this.codeElement.nativeElement);
}
没问题...
但是,如果我改为
success(data:any){
this.submission = data;
this.criteria = data.criteria;
this.codeString = data.code;
hljs.highlightBlock(this.codeElement.nativeElement);
}
我明白了:
我做错了什么?
HTML 是一样的
<pre>
<code #code highlight class="java">
{{codeString}}
</code>
</pre>
如@PankajParkar 评论中所述,highlightBlock
在 codeString
绑定得到评估之前就开始火了。
推迟 运行 此功能到下一个报价单(使用 setTimeout
)将起作用,因为它将允许 Angular 进行更改检测和 DOM 更新。
另一种解决方案是使用管道。这是我使用 Prism.js 用于代码突出显示的管道。您可以轻松更新它以使用 Highlight.js:
@Pipe({ name: 'prism' })
export class PrismPipe implements PipeTransform {
constructor(private sanitizer: DomSanitizer) {}
transform(value, args) {
if (!isString(value)) {
throw new InvalidPipeArgumentException(PrismPipe, value);
}
let lang = args[0].toString().trim().toLowerCase();
let grammar = Prism.languages[lang];
// fallback to clike
if (!grammar) grammar = Prism.languages.clike;
return this.sanitizer.bypassSecurityTrustHtml(Prism.highlight(value, grammar));
}
}
然后我在这样的代码中使用它:
<pre [innerHtml]="codeString.source | prism:codeString.lang"></pre>
这是因为 highlightBlock
函数在内部 code
元素内容不可用之前启动。解决方案之一是 setTimeout
应用 highlightBlock
一个勾后,一旦所有绑定都被应用。但不必要的是,这将使 运行 成为另一个变化检测。
与其等待内部内容以 DOM 为界,不如手动将其应用于 DOM 的 textContent,然后应用 highlightBlock
函数。
代码
success(data:any){
this.submission = data;
this.criteria = data.criteria;
this.codeString = data.code;
//making sure code is populated by below line
this.codeElement.nativeElement.textContent = data.code;
hljs.highlightBlock(this.codeElement.nativeElement);
}
在 Angular4 中,要使用来自组件的 highlight.js:
import {Component, ViewEncapsulation} from '@angular/core';
import * as hljs from 'highlight.js';
@Component({
selector: 'cus-com',
template: `
<pre>
<code [innerHtml]="html_content"></code>
</pre>`,
encapsulation: ViewEncapsulation.None,
styles: [require('highlight.js/styles/github.css')]
})
export class CustomComponentsComponent {
languages = ['html', 'typescript'];
html_content = hljs.highlightAuto('<h1 class="big">Title</h1>', this.languages).value;
}
我正在尝试在我的 Angular 2 应用程序中使用 Highlight JS,当代码块不是静态信息时,我在弄清楚如何使用它时遇到了一些麻烦。我的意思是,代码字符串来自服务器通过 http get 调用。
所以,如果我有这个:
export class WorkstationComponent implements OnInit {
private submission = new Submission();
private criteria = new Array<ExerciseCriteria>();
private codeString:string = `
/* HelloWorld.java
*/
public class HelloWorld
{
public static void main(String[] args) {
System.out.println("Hello World!");
}
}`;
constructor(private _router:Router, private submissionService:SubmissionService,
private activatedRoute:ActivatedRoute){}
@ViewChild('code') codeElement: ElementRef;
ngOnInit(){
this.activatedRoute.params
// (+) converts string 'id' to a number
.switchMap((params: Params) => this.submissionService.getSubmission(+params['id']))
.subscribe(data => this.success(data),
error => this.fail(error));
}
success(data:any){
this.submission = data;
this.criteria = data.criteria;
hljs.highlightBlock(this.codeElement.nativeElement);
}
没问题...
但是,如果我改为
success(data:any){
this.submission = data;
this.criteria = data.criteria;
this.codeString = data.code;
hljs.highlightBlock(this.codeElement.nativeElement);
}
我明白了:
我做错了什么? HTML 是一样的
<pre>
<code #code highlight class="java">
{{codeString}}
</code>
</pre>
如@PankajParkar 评论中所述,highlightBlock
在 codeString
绑定得到评估之前就开始火了。
推迟 运行 此功能到下一个报价单(使用 setTimeout
)将起作用,因为它将允许 Angular 进行更改检测和 DOM 更新。
另一种解决方案是使用管道。这是我使用 Prism.js 用于代码突出显示的管道。您可以轻松更新它以使用 Highlight.js:
@Pipe({ name: 'prism' })
export class PrismPipe implements PipeTransform {
constructor(private sanitizer: DomSanitizer) {}
transform(value, args) {
if (!isString(value)) {
throw new InvalidPipeArgumentException(PrismPipe, value);
}
let lang = args[0].toString().trim().toLowerCase();
let grammar = Prism.languages[lang];
// fallback to clike
if (!grammar) grammar = Prism.languages.clike;
return this.sanitizer.bypassSecurityTrustHtml(Prism.highlight(value, grammar));
}
}
然后我在这样的代码中使用它:
<pre [innerHtml]="codeString.source | prism:codeString.lang"></pre>
这是因为 highlightBlock
函数在内部 code
元素内容不可用之前启动。解决方案之一是 setTimeout
应用 highlightBlock
一个勾后,一旦所有绑定都被应用。但不必要的是,这将使 运行 成为另一个变化检测。
与其等待内部内容以 DOM 为界,不如手动将其应用于 DOM 的 textContent,然后应用 highlightBlock
函数。
代码
success(data:any){
this.submission = data;
this.criteria = data.criteria;
this.codeString = data.code;
//making sure code is populated by below line
this.codeElement.nativeElement.textContent = data.code;
hljs.highlightBlock(this.codeElement.nativeElement);
}
在 Angular4 中,要使用来自组件的 highlight.js:
import {Component, ViewEncapsulation} from '@angular/core';
import * as hljs from 'highlight.js';
@Component({
selector: 'cus-com',
template: `
<pre>
<code [innerHtml]="html_content"></code>
</pre>`,
encapsulation: ViewEncapsulation.None,
styles: [require('highlight.js/styles/github.css')]
})
export class CustomComponentsComponent {
languages = ['html', 'typescript'];
html_content = hljs.highlightAuto('<h1 class="big">Title</h1>', this.languages).value;
}