Angular 2中的语法高亮显示
我正在使用angular 2创建简单的web应用程序。我有两个部分。第一个基本上是包含一些数据行的表。执行“单击行”时,与行相对应的数据将显示在第二个组件中。数据是XML,加载到代码元素。看起来像Angular 2中的语法高亮显示,angular,syntax-highlighting,Angular,Syntax Highlighting,我正在使用angular 2创建简单的web应用程序。我有两个部分。第一个基本上是包含一些数据行的表。执行“单击行”时,与行相对应的数据将显示在第二个组件中。数据是XML,加载到代码元素。看起来像 @Component export class TableComponent { items: Data[]; selectedItemsXml: string; // ...other stuff //when row is clicked toggleSe
@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回购协议出现问题后,我把它扔掉了。我接下来尝试的是基于以下帖子使用highlight.js创建指令:。使用此方法突出显示Xml,但仅在第一次单击行时突出显示。单击另一行时,甚至不会显示新的xml。我也尝试过使用prism.js,但我得到了相同的行为。一旦某个xml字符串第一次绑定、显示在代码元素中并使用highlight.js或prism.js高亮显示,它将保持不变
我猜这与angular 2中DOM和数据绑定的工作方式有关,因为在不使用语法高亮显示的情况下,每次选择行时,我都会绑定字符串并将其传递给代码元素。使用高亮显示可以绑定字符串,将其传递给代码元素,然后对其进行预加密。这意味着代码元素中没有简单的字符串,而是有很多样式化的span元素,这会导致在选择新行时加载新xml字符串时出现问题。我还尝试使用Prism.highlight(text_to_pretified)绑定“pre-pre-pretified”字符串,但使用此方法会导致显示包含由Prism添加的所有span元素的xml
现在,我正在绞尽脑汁思考如何解决这个问题。请给我一些动力,我如何才能使它工作。我将创建一个利用PRISMJ的组件 包括prismjs脚本,包括所需组件文件夹中的任何脚本 Index.html
安装Prism的最新类型定义文件(这将为您提供类型安全):
npm安装@ryancavanaugh/prismjs
注意:不要安装@types/prismjs-它可能已过期或编写不正确。prismjs
的作者推荐@ryancvanaugh/prismjs作为类型定义
将文件夹添加到tsconfig.json
中的typeRoots
列表属性中,以便typescript编译器可以找到它:
tsconfig.json(在编译器选项下)
“类型根”:[
“节点\模块/@类型”,
“节点_模块/@ryancavanaugh”
]
创建调用prism的自定义prism
组件。突出显示:
prism.component.ts
//
导入{
组成部分,
AfterViewInit,
输入,
ElementRef,
视图儿童
}从“@angular/core”开始;
@组成部分({
moduleId:module.id,
选择器:“棱镜”,
模板:`
像这样使用它:
var x=3;
T类
{{ '{' }}
{{ '}' }}
您可以尝试我为Angular 2/4编写的这个简单组件,因为它已不再维护,并且不适用于最新的Angular版本。我使用PixelBits解决方案,只需进行少量更改,首先确保您不在App.component.ts文件中尝试prism组件,您将获得“检查后视图已更改”如果重新加载页面,将不会调用error和ngAfterViewInit()。因此,请创建一个基本路由,并创建一个页面,然后在该新页面中尝试使用prism组件。
接下来,如果您想使用行号插件,Prism.highlight将无法工作。您需要使用Prism.highlightElement。
同样,使用PixelBits解决方案,您可以在代码前后获得空白空间。
不要忘记更改引用路径url,使其与您的项目匹配
ts:
和html:
另外,我没有使用npm获取prism.js,但我是从prism官方网站获取的(行号插件集成在prism.js中)。我不确定“选择新行时加载新xml字符串”是什么意思。你能澄清这个问题吗?您好,我添加了一个简短的代码示例。现在可能更清楚了。我能够将这个答案与@Vaibhav提供的回购协议结合起来使用。多亏了大家!我遇到了一个错误:error ReferenceError:Prism在尝试调用this.content=Prism.highli时未定义
ght(this.rawContent.nativeElement.innerHTML,Prism.languages[this.language]);
在我的Prism组件上:(angular prism对我来说工作得很好。我花了很长时间制作了自己的,这就更好了。谢谢你!使用你制作的东西和最初的prism源代码,我编写了一个版本,在typescript/angular 2/4中本机工作,而无需导入任何单独的、普通的javascript库。它只是一个服务、一个组件,以及用于语法主题,打包到NgModule中。我以前从未向Github贡献过任何东西,所以我对它的工作原理一无所知。我应该创建一个全新的回购并将其作为单独的东西上传吗?还是应该将其贡献给您的,看看您是否可以将其合并?@diopside您可以使用一个Yeoman生成器来创建gular library软件包。一旦成功,将代码推送到git repo,您还可以在npm上发布您的模块。您可以在internet上轻松找到所有这些步骤的指南
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);
}
}
<pre class="line-numbers"><code #codeRef [innerHTML]="content" [class]="myClass"></code></pre>
<div style="display: none;" hidden="true" #rawContent>
<ng-content></ng-content>
</div>