在Angular 2

时间:2016-11-19 13:40:34

标签: angular highlight

我试图在我的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

但是,如果我改为

success(data:any){
    this.submission = data;
    this.criteria = data.criteria;
    this.codeString = data.code;
    hljs.highlightBlock(this.codeElement.nativeElement);
}

我明白了:

fail

我做错了什么? HTML是相同的

                <pre>
                    <code #code highlight class="java">
                        {{codeString}}
                    </code>
                </pre>

3 个答案:

答案 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:

&#13;
&#13;
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;
&#13;
&#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>