2017-04-01 6 views
2

私は角度2を使って簡単なWebアプリケーションを作成しています。私はそこに2つのコンポーネントを持っています。最初は基本的にいくつかのデータ行を持つテーブルです。クリックが行なわれると、行に対応するデータが第2のコンポーネントに表示される。データはXMLであり、コード要素にロードされます。それは何かのように見える構文2角度2で強調表示

@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> 

xmlのシンタックスハイライトを追加するまで、すべてうまくいきました。まず、ng2-prismプラグインを使いたかったのですが、正しく動作させるには問題がありました。 git repoで問題を見つけた後、私はそれを投げ捨てました。次に試したのは、この投稿に基づいてhighlight.jsを使用してディレクティブを作成することでした:highlight.js does not work with Angular 2。このメソッドを使用してXmlが強調表示されますが、最初の行のみがクリックされます。別の行をクリックすると、新しいxmlは表示されません。私もprism.jsを使用しようとしましたが、私は同じ動作をしています。一部のXML文字列が最初にバインドされ、コード要素に表示され、highlight.jsまたはprism.jsを使用して強調表示されると、それも残ります。

構文ハイライトを使用しないと、行が選択されるたびにコード要素にバインドして文字列を渡すので、角度2でDOMとデータバインディングがどのように機能するかは関係ありません。強調表示の原因を使用して文字列をバインドし、それをコード要素に渡してから、それを予期します。つまり、コード要素内に単純な文字列はありませんが、多くのスタイルのスパン要素があり、新しい行が選択されたときに新しいXML文字列をロードする問題が発生します。私はまた、Prism.highlight(text_to_prettify)を使って "pre-prettified"文字列をバインドしようとしましたが、このメソッドを使用すると、Prismによって追加されたすべてのspan要素を含むXMLが表示されます。

今、私はこの問題を解決する方法を考えている私の頭を傷つけています。どのように私はそれを働かせることができるか私にいくつかのプッシュを与えてください。

+0

「新しい行が選択されたときに新しいXML文字列をロードする」という意味がわかりません。問題を明確にすることができますか? – pixelbits

+0

こんにちは、短縮コード例を追加しました。多分今はもっと明白でしょう。 –

答えて

3

私はprismjsを利用するコンポーネントを作成します。

必要なコンポーネントフォルダのいずれかを含むprismjsスクリプトを含めます。

Index.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> 

(これはあなたが型の安全性を与える)プリズムの最新のタイプ定義ファイルをインストールします。

npm install @ryancavanaugh/prismjs 

注:タイプ@インストールしないでください/ prismjs - 古くなっているか正しく作成されていません。 prismjsの著者は、タイプ定義に@ ryancvanaugh/prismjsを推奨しています。

typescriptですコンパイラがそれを見つけることができるようにtsconfig.jsonであなたのtypeRootsリストプロパティにフォルダを追加します。

tsconfig.json(compilerOptions下)

"typeRoots": [ 
    "node_modules/@types", 
    "node_modules/@ryancavanaugh" 
] 

を呼び出すカスタムprismコンポーネントを作成します。 Prism.highlight

prism.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]); 
    } 
} 

アプリ内にプリズムコンポーネントを宣言します。モジュール:

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 { } 

このようにそれを使用します。

<prism language="csharp"> 
    var x = 3; 
    class T 
    {{ '{' }} 
    {{ '}' }} 
</prism> 
+0

私は、以下の@Vaibhavによって提供されたこの回答とレポを組み合わせて作業することができました。ありがとうございます! –

2

あなたはng2-prismがノーであるので、私は角2/4のために書いたこの単純なangular-prismコンポーネントを試すことができます長く維持され、最新の角型リリースでは機能しません。

+0

角プリズムは私のためにうまくいきました。私は年を費やして自分自身を作りましたが、これははるかに優れています。 – rjdkolb

+0

ありがとうございます!あなたが作ったものと元のプリズムのソースを使って、別のバニラのjavascriptライブラリをインポートせずに、typescript/Angular 2/4でネイティブに動作するバージョンを作った。 NgModuleにパッケージ化された構文テーマ用のサービス、コンポーネント、および任意のCSS。私はGithubに何も貢献したことはありません。その前に、私はこれがどういう仕組みになっているかわかりません。全く新しいリポジトリを作成して別のものとしてアップロードする必要がありますか?または、私はそれをあなたのものに寄付し、あなたがそれを組み入れることができるかどうかを見なければなりませんか? – diopside

+0

@diopside角度ライブラリパッケージの作成に使用できるYeomanジェネレータの1つを使用できます。いったん動作したら、コードをgit repoにプッシュし、npmにモジュールを公開することもできます。これらすべての手順について、インターネット上のガイドを簡単に見つけることができます –

0

私はPixelBitsソリューションを使用していますが、変更はほとんどありません。まず、App.component.tsファイルでプリズムコンポーネントを試していないことを確認します。「確認後に変更されたビュー」エラーとngAfterViewInit )は、ページをリロードすると呼び出されません。したがって、基本的なルーティングとページを作成し、その新しいページの中にプリズムコンポーネントを試してみてください。 次の行番号プラグインを使用する場合、Prism.highlightは機能しません。 Prism.highlightElementを使用する必要があります。 また、PixelBitsソリューションでは、コードの前後に空きスペースがあります。 参照パスのURLがプロジェクトと一致するように変更することを忘れないでください。

TS:

export class PrismComponent implements OnInit,AfterViewInit { 
    @Input() language: string; 
    @ViewChild("rawContent") rawContent: ElementRef; 
    @ViewChild("codeRef") codeRef: ElementRef; 
    content: string; 
    myClass:string; 

    constructor(
     private elementRef:ElementRef, 
    ) { 
    } 

    ngOnInit(){ 
     this.myClass = "language-" + this.language; 
    } 

    ngAfterViewInit() { 
     // trim because ng-content add space 
     this.content = this.rawContent.nativeElement.innerHTML.trim(); 
     // make line number plugin work. 
     Prism.highlightElement(this.codeRef.nativeElement,true); 
    } 
} 

とhtml:

<pre class="line-numbers"><code #codeRef [innerHTML]="content" [class]="myClass"></code></pre> 
<div style="display: none;" hidden="true" #rawContent> 
    <ng-content></ng-content> 
</div> 

も、私はprism.jsを取得するためにNPMを使用していないが、私は公式プリズムのウェブサイトから、それを取った(ライン - のためのプラグインnumberはprism.js内に組み込まれています)。

関連する問題