我试图在我的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>
答案 0 :(得分:2)
这种情况正在发生,因为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);
}
答案 1 :(得分:0)
在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;
}
&#13;
答案 2 :(得分:-1)
如@PankajParkar评论中所述,highlightBlock
在评估codeString
绑定之前就会着火。
将此函数推迟到下一个tick(使用setTimeout
)将会起作用,因为它将允许Angular进行更改检测和DOM更新。
另一种解决方案是使用Pipe。这是我使用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>