2016-11-19 163 views
2

我試圖在我的Angular 2應用程序中使用Highlight JS,並且在代碼塊不是靜態信息時遇到了一些麻煩。我的意思是,代碼字符串通過http get調用來自服務器。在Angular 2中使用Highlight JS

所以,如果我有這樣的:

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> 
+2

我的猜測是'highlightBlock'之前'codeString'越來越火綁定被評估。您可能需要等待下一個勾號並調用'highlightBlock'函數。就像通過'setTimeout(()=> {hljs.highlightBlock(this.codeElement.nativeElement);},0);'而不是'hljs.highlightBlock(this.codeElement.nativeElement);' –

回答

2

它發生,因爲highlightBlock功能在內code元素含量ISN之前讓火不可用。解決方案之一是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); 
} 
+0

setTimeout方法適用於我。 獲取錯誤「this.codeElement.nativeElement。textContent不是函數「與第二種方法 –

+1

@ ManuelZamith Ahh .. textContent屬性不是一種方法(我錯誤地有方法在那裏:()..檢查更新的答案,它應該工作:) –

+0

輝煌:)。謝謝那麼多。 –

-1

正如@PankajParkar評論中提及,highlightBlockcodeString前得到消防結合被評估。

推遲將此函數運行到下一個勾號(使用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> 
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; 
 
}