2017-04-01 6 views
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과 데이터 바인딩이 작동하는 방식과 관련이 있습니다. 강조 표시 원인을 사용하여 문자열을 바인딩하고 코드 요소에 전달한 다음이를 미리 적용합니다. 즉, 코드 요소 안에 간단한 문자열이 없지만 많은 스타일의 span 요소가 있다는 의미입니다. 새 행을 선택하면 새 XML 문자열을로드하는 데 문제가 발생합니다. 또한 Prism.highlight (text_to_prettify)를 사용하여 "pre-prettified"문자열을 바인딩하려고 시도했지만이 방법을 사용하면 프리즘에 의해 추가 된 모든 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를 권장합니다. 호출하는 사용자 정의 prism 구성 요소 만들기 (compilerOptions 아래)

tsconfig.json

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

을 :

그래서 타이프 스크립트 컴파일러를 찾을 수 tsconfig.jsontypeRoots 목록 속성에 폴더 추가 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]); 
    } 
} 

응용 프로그램에서 프리즘 구성 요소를 선언하십시오.모듈 :

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

나는이 답변과 @Vaibhav가 제공하는 repo를 조합하여 작업 할 수있었습니다. 모두에게 감사드립니다! –

2

당신은 내가 ng2-prism 때문에 각도 2/4를 위해 쓴이 간단한 angular-prism 구성 요소를 시도 할 수는없는 것입니다 :

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

이처럼 사용 app.module.ts 유지 보수 기간이 오래 걸리고 최신 각진 릴리스에서 작동하지 않습니다.

+0

앵글 프리즘은 나를 위해 잘 작동했습니다. 나는 나이를 내 자신의 것으로 만드는 데 썼다. 그리고 이것은 훨씬 좋다. – rjdkolb

+0

고맙습니다! 당신이 만든 프리즘 소스와 원래의 프리즘 소스를 사용하여 필자는 별도의 바닐라 자바 ​​스크립트 라이브러리를 가져 오지 않고도 typescript/Angular 2/4에서 기본적으로 작동하는 버전을 작성했습니다. NgModule에 패키지 된 구문 테마를위한 서비스, 구성 요소 및 CSS. 나는 전에 Github에 어떤 것을 기여한 적이 없기 때문에 나는 이것이 어떻게 작동하는지 꽤 우둔합니다. 완전히 새로운 저장소를 만들어 별도의 항목으로 업로드해야합니까? 아니면 내가 당신에게 그것을 기부해야하고, 당신이 그것을 통합 할 수 있는지 알아야합니까? – diopside

+0

@diopside 각도 라이브러리 패키지를 만드는 데 사용할 수있는 Yeoman 생성기 중 하나를 사용할 수 있습니다. 일단 작동하면 코드를 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 내에 통합되어 있습니다.)