前言
微軟之前有個項目叫做Monaco Workbench,後來這個項目變成了VS Code,而Monaco Editor就是從這個項目中成長出來的一個web編輯器,是以Monaco Editor和VS Code在編輯代碼,互動以及UI上幾乎是一摸一樣的,有點不同的是,兩者的平台不一樣,Monaco Editor基于浏覽器,而VS Code基于electron,是以功能上VSCode更加健全,并且性能比較強大。本文主要介紹ng-zorro 架構內建Monaco Editor實作文本比對。Monaco Editor 不僅能做文本比對,同樣可以做代碼編輯器,可以查閱《使用微軟Monaco Editor 編寫線上調試工具》。
環境及元件
Monaco Editor 微軟 Monaco Editor 編輯器
Ant Design of Angular NG-ZORRO
ngx-monaco-editor monaco-editor angular npm 包
實作
根據 ngx-monaco-editor 文檔按angular版本安裝指定版本的npm包
注意:版本對應不上會導緻資源404錯誤
- Angular <= 4: v3.x.x
- Angular 5: v5.x.x
- Angular 6: v6.x.x
- Angular 7: v7.x.x
- Angular 8: v8.x.x
- Angular 9: v9.x.x
npm install [email protected] --save
接下來配置全局靜态資源
Angular 6 之前版本 添加到.angular-cli.json檔案中
{
"options": {
{
"assets": [
{ "glob": "**/*", "input": "node_modules/ngx-monaco-editor/assets/monaco", "output": "./assets/monaco/" }
],
...
}
...
},
...
}
Angular 6 之後版本 添加到.angular.json檔案中
{
"apps": [
{
"assets": [
{ "glob": "**/*", "input": "../node_modules/ngx-monaco-editor/assets/monaco", "output": "./assets/monaco/" }
],
...
}
...
],
...
}
Angular 子產品檔案中配置
DiffEditorModule
import { NgModule } from '@angular/core';
import { DiffEditorRoutingModule } from './diff-editor-routing.module';
import { DiffEditorComponent } from './diff-editor.component';
import { NgZorroAntdModule } from 'ng-zorro-antd';
import { CommonModule } from '@angular/common';
import { ClipboardModule } from 'ngx-clipboard';
import { FormsModule } from '@angular/forms';
import { MonacoEditorModule } from 'ngx-monaco-editor';
@NgModule({
imports: [
CommonModule,
DiffEditorRoutingModule,
NgZorroAntdModule,
ClipboardModule,
FormsModule,
MonacoEditorModule.forRoot(),
],
declarations: [DiffEditorComponent],
exports: [DiffEditorComponent]
})
export class DiffEditorModule { }
Monaco Editor 支援選擇文本語言、編輯器主題等等配置,我們同樣在頁面上也支援這些配置項動态配置,結合阿裡的NG-ZORRO架構,完整代碼如下:
<div nz-row [nzGutter]="16">
<div nz-col class="gutter-row" [nzSpan]="24" *ngIf="isCompared">
<nz-select [(ngModel)]="selectedLang" class="lang-select ditor-config" (ngModelChange)="onChangeLanguage($event)">
<nz-option *ngFor="let option of languages" [nzValue]="option" [nzLabel]="option"></nz-option>
</nz-select>
<nz-select [(ngModel)]="selectedTheme" class="lang-select ditor-config" (ngModelChange)="onChangeTheme($event)">
<nz-option *ngFor="let option of themes" [nzValue]="option.value" [nzLabel]="option.name"></nz-option>
</nz-select>
<nz-switch class="ditor-config" [(ngModel)]="switchValue" [nzControl]="true" (click)="onChangeInline()" nzCheckedChildren="開啟内聯差異"
nzUnCheckedChildren="關閉内聯差異"></nz-switch>
<button class="ditor-config" nz-button nzType="primary" (click)="onClear()">傳回</button>
</div>
<div nz-col class="gutter-row diff-editor-row" [nzSpan]="24" *ngIf="isCompared">
<ngx-monaco-diff-editor style="height: 100%" [options]="options" [originalModel]="originalModel" [modifiedModel]="modifiedModel">
</ngx-monaco-diff-editor>
</div>
<div nz-col class="gutter-row" [nzSpan]="24" *ngIf="!isCompared">
<button class="ditor-config" nz-button nzType="primary" (click)="onCompare()">比對文本</button>
</div>
<div nz-col class="gutter-row" [nzSpan]="12" *ngIf="!isCompared">
<textarea nz-input placeholder="請輸入比對文本" [nzAutosize]="{ minRows: 10, maxRows: 29 }" [(ngModel)]="text1"></textarea>
</div>
<div nz-col class="gutter-row" [nzSpan]="12" *ngIf="!isCompared">
<textarea nz-input placeholder="請輸入比對文本" [nzAutosize]="{ minRows: 10, maxRows: 29 }" [(ngModel)]="text2"></textarea>
</div>
</div>
import { Component, Input, OnInit, Output } from '@angular/core';
import { DiffEditorModel } from "ngx-monaco-editor";
import { Title } from '@angular/platform-browser';
@Component({
selector: 'app-diff-editor',
templateUrl: './diff-editor.component.html',
styleUrls: ['./diff-editor.component.less']
})
export class DiffEditorComponent implements OnInit {
constructor(private titleService: Title) {
}
text1 = "";
text2 = "";
selectedLang = "plaintext";
selectedTheme = "vs";
languages = [
"bat",
"c",
"coffeescript",
"cpp",
"csharp",
"csp",
"css",
"dockerfile",
"fsharp",
"go",
"handlebars",
"html",
"ini",
"java",
"javascript",
"json",
"less",
"lua",
"markdown",
"msdax",
"mysql",
"objective-c",
"pgsql",
"php",
"plaintext",
"postiats",
"powershell",
"pug",
"python",
"r",
"razor",
"redis",
"redshift",
"ruby",
"rust",
"sb",
"scss",
"sol",
"sql",
"st",
"swift",
"typescript",
"vb",
"xml",
"yaml"
];
themes = [
{
value: "vs",
name: "Visual Studio"
},
{
value: "vs-dark",
name: "Visual Studio Dark"
},
{
value: "hc-black",
name: "High Contrast Dark"
}
];
options = {
theme: "vs",
language: "plaintext",
readOnly: true,
renderSideBySide: true
};
originalModel: DiffEditorModel = {
code: "",
language: "plaintext"
};
modifiedModel: DiffEditorModel = {
code: "",
language: "plaintext"
};
switchValue = false;
isCompared = false;
public ngOnInit() {
this.titleService.setTitle('碼加線上工具 - 文本比對');
}
onChangeLanguage(language) {
this.options = Object.assign({}, this.options, {
language: language
});
this.originalModel = Object.assign({}, this.originalModel, {
language: language
});
this.modifiedModel = Object.assign({}, this.modifiedModel, {
language: language
});
}
onChangeTheme(theme) {
this.options = Object.assign({}, this.options, { theme: theme });
}
onChangeInline() {
this.options = Object.assign({}, this.options, {
renderSideBySide: this.switchValue
});
this.switchValue = !this.switchValue;
}
onCompare() {
this.originalModel = Object.assign({}, this.originalModel, {
code: this.text1
});
this.modifiedModel = Object.assign({}, this.modifiedModel, {
code: this.text2
});
this.isCompared = true;
}
onClear() {
this.isCompared = false;
}
}
運作結果如下:
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmL0gjN5QTMzQTMyAjNwEjMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.gif)
完美運作
最後推薦一個比較幹淨實用的線上工具 http://tool.codeplus.vip/