Angular 2中的语法突出显示

Ano*_*oob 4 syntax-highlighting angular

我正在使用angular 2创建简单的Web应用程序。这里有两个组件。首先基本上是带有一些数据行的表。当单击行时,与行对应的数据将显示在第二个组件中。数据是XML,并加载到代码元素中。看起来像

@Component
export class TableComponent {
    items: Data[];
    selectedItemsXml: string;
    // ...other stuff

    //when row is clicked
    toggleSelectedRow(rowIndex: number) {
        // ...other stuff related to change row's background color
        this.selectedItemsXml = this.items[i].xml;
    }
    // ...other stuff again
}

//TableComponent's template
<div>
    <table>
        ...
        ...*ngFor="let item of items; let i = index;"...
        <tr (click)="toggleSelectedRow(i)">
            <td>{{item.id}}</td>
            <td>{{item.time}}</td>
        </tr>
        ...
    </table>
</div>
<xml-detail [xml]="selectedItemsXml"></xml-detail>

@Component
export class XmlDetailComponent {
    @Input() xml: string;
}

//XmlDetailComponent's template
<div>
    <pre><code>{{xml}}</code></pre>
</div>
Run Code Online (Sandbox Code Playgroud)

一切工作正常,直到我想为xml添加语法突出显示。首先,我想使用插件ng2-prism,但是我遇到了使其无法正常运行的问题。在git repo中看到问题后,我将其丢弃。我接下来尝试的是根据这篇文章使用Highlight.js创建指令:Highlight.js不适用于Angular 2。使用此方法突出显示Xml,但仅单击第一行。单击另一行时,甚至不显示新的xml。我也尝试使用了prism.js,但是我得到了相同的行为。首次绑定某些xml字符串后,将其显示在代码元素中,并使用highlight.js或prism.js对其进行突出显示,它将保留。

我的猜测是它与DOM和数据绑定在angular 2中的工作方式有关,因为在不使用语法突出显示的情况下,我将每次选择行时都将字符串绑定并传递给代码元素。使用突出显示会绑定字符串,将其传递给代码元素,然后进行美化。这意味着在代码元素内没有简单的字符串,但是有很多样式化的span元素,这在选择新行时导致加载新xml字符串时出现问题。我还尝试使用Prism.highlight(text_to_prettify)绑定“预先设置”的字符串,但是使用此方法会导致显示xml与Prism添加的所有span元素。

现在,我正在思考如何解决此问题。请给我一些推动,我该如何使其工作。

pix*_*its 5

我将创建一个利用prismjs 的组件。

包括prismjs 脚本,包括您需要的components 文件夹中的任何脚本。

索引.html

<link href="node_modules/prismjs/themes/prism.css" rel="stylesheet" />
<script src="node_modules/prismjs/prism.js"></script>
<script src="node_modules/prismjs/components/prism-core.js"></script>
<script src="node_modules/prismjs/components/prism-clike.js"></script>
<script src="node_modules/prismjs/components/prism-csharp.js"></script>
Run Code Online (Sandbox Code Playgroud)

为 Prism 安装最新的类型定义文件(这将为您提供类型安全性):

npm install @ryancavanaugh/prismjs
Run Code Online (Sandbox Code Playgroud)

注意:不要安装@types/prismjs - 它要么是过时的,要么是没有正确编写的。作者prismjs推荐 @ryancvanaugh/prismjs 用于类型定义。

将该文件夹添加到您的typeRoots列表属性中,tsconfig.json以便打字稿编译器可以找到它:

tsconfig.json(在 compilerOptions 下)

"typeRoots": [
  "node_modules/@types",
  "node_modules/@ryancavanaugh"
]
Run Code Online (Sandbox Code Playgroud)

创建一个prism调用的自定义组件Prism.highlight

棱镜.component.ts

/// <reference path="../node_modules/@ryancavanaugh/prismjs/prism.d.ts" />
import { 
    Component, 
    AfterViewInit, 
    Input, 
    ElementRef, 
    ViewChild 
} from '@angular/core';

@Component({
    moduleId: module.id,
    selector: 'prism',
    template: `
        <div hidden="true" #rawContent>
            <ng-content></ng-content>
        </div>
        <pre>
            <code [innerHTML]="content">
            </code>
        </pre>

    `
})
export class PrismComponent implements AfterViewInit {
    @Input() language: string;
    @ViewChild("rawContent") rawContent: ElementRef;
    content: string;

    constructor(private elementRef:ElementRef) {
     }

    ngAfterViewInit() {
        this.content = Prism.highlight(this.rawContent.nativeElement.innerHTML, Prism.languages[this.language]);
     }
}
Run Code Online (Sandbox Code Playgroud)

在 app.module 中声明 Prism 组件:

app.module.ts

import { NgModule } from '@angular/core';
import { BrowserModule  } from '@angular/platform-browser';
import { HttpModule } from '@angular/http';

import { AppComponent } from './app.component';
import { PrismComponent } from './prism.component';

@NgModule({
    imports: [
        BrowserModule,
        HttpModule        
        ],
    declarations: [AppComponent, PrismComponent],
    providers: [/* TODO: Providers go here */],
    bootstrap: [AppComponent],
})
export class AppModule { }
Run Code Online (Sandbox Code Playgroud)

像这样使用它:

<prism language="csharp">
    var x = 3;
    class T
    {{ '{' }}
    {{ '}' }}
</prism>
Run Code Online (Sandbox Code Playgroud)


Vai*_*sal 5

您可以尝试我为Angular 2/4编写的这个简单的angular-prism组件,因为ng2-prism不再维护,并且不适用于最新的angular版本。