微软之前有个项目叫做Monaco Workbench,后来这个项目变成了VS Code,而Monaco Editor就是从这个项目中成长出来的一个web编辑器,所以Monaco Editor和VS Code在编辑代码,交互以及UI上几乎是一摸一样的,有点不同的是,两者的平台不一样,Monaco Editor基于浏览器,而VS Code基于electron,所以功能上VSCode更加健全,并且性能比较强大。本文主要介绍ng-zorro 框架集成Monaco Editor实现HTML 在线调试器。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错误
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 模块文件中配置 MonacoEditorModule
import {
BrowserModule } from '@angular/platform-browser';
import {
NgModule } from '@angular/core';
import {
FormsModule } from '@angular/forms';
import {
AppComponent } from './app.component';
import {
MonacoEditorModule } from 'ngx-monaco-editor';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
FormsModule,
MonacoEditorModule.forRoot() // use forRoot() in main app module only.
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule {
}
页面使用tab标签页实现HTML、JS、CSS 多个代码编辑器切换
<nz-tabset>
<nz-tab nzTitle="HTML">
<ngx-monaco-editor [options]="htmlEditorOptions" [(ngModel)]="htmlCode">ngx-monaco-editor>
nz-tab>
<nz-tab nzTitle="JAVASCRIPT">
<ngx-monaco-editor [options]="jsEditorOptions" [(ngModel)]="jsCode">ngx-monaco-editor>
nz-tab>
<nz-tab nzTitle="CSS">
<ngx-monaco-editor [options]="cssEditorOptions" [(ngModel)]="cssCode">ngx-monaco-editor>
nz-tab>
nz-tabset>
我以为这样就可以完美展示三个编辑器了,可现实往往是让人头痛的
在 tabs 中添加多个实例竟然不行,于是我尝试着不放在tabs中实现,结果却是可以的。
初步估计是加载顺序的问题,于是我把每个 ngx-monaco-editor 标签 封装成了组件,修整了一下数据获取逻辑,完整代码如下:
<div nz-row [nzGutter]="16">
<div nz-col class="gutter-row code-view" [nzSpan]="12">
<nz-tabset [nzAnimated]="true" [nzTabBarExtraContent]="extraTemplate">
<nz-tab [nzTitle]="htmlTitleTemplate" (nzDeselect)="onDeselect()">
<ng-template nz-tab>
<code-view-eagerly #htmlCodeEagerly [(code)]="htmlCode" [options]="htmlEditorOptions">code-view-eagerly>
ng-template>
<ng-template #htmlTitleTemplate> <i nz-icon [nzIconfont]="'iconHTML'">i>HTMLng-template>
nz-tab>
<nz-tab [nzTitle]="jsTitleTemplate" (nzDeselect)="onDeselect()">
<ng-template nz-tab>
<code-view-eagerly #jsCodeEagerly [(code)]="jsCode" [options]="jsEditorOptions">code-view-eagerly>
ng-template>
<ng-template #jsTitleTemplate> <i nz-icon [nzIconfont]="'iconJS'">i>JAVASCRIPTng-template>
nz-tab>
<ng-template nz-tab>
<code-view-eagerly #cssCodeEagerly [(code)]="cssCode" [options]="cssEditorOptions">code-view-eagerly>
ng-template>
<ng-template #cssTitleTemplate> <i nz-icon [nzIconfont]="'iconCSS'">i>CSSng-template>
nz-tab>
nz-tabset>
<ng-template #extraTemplate>
<button nz-button nzType="primary" (click)="runAllCodes()">运行代码button>
ng-template>
div>
<div nz-col class="gutter-row" [nzSpan]="12">
<iframe class="view-panel" id="preview" frameborder="0">iframe>
div>
div>
import {
THIS_EXPR } from '@angular/compiler/src/output/output_ast';
import {
Component, forwardRef, Input, OnInit, Output, ViewChild } from '@angular/core';
import {
ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
@Component({
selector: 'app-code-view',
templateUrl: './code-view.component.html',
styleUrls: ['./code-view.component.less']
})
export class CodeViewComponent implements OnInit {
//html
htmlEditorOptions = {
theme: "vs-dark",
language: "html",
};
htmlCode: string = '';
//javascript
jsEditorOptions = {
theme: "vs-dark",
language: "javascript",
};
jsCode: string;
//javascript
cssEditorOptions = {
theme: "vs-dark",
language: "css",
};
cssCode: string;
@ViewChild('htmlCodeEagerly') htmlCodeEagerly: CodeViewEagerlyComponent;
@ViewChild('jsCodeEagerly') jsCodeEagerly: CodeViewEagerlyComponent;
@ViewChild('cssCodeEagerly') cssCodeEagerly: CodeViewEagerlyComponent;
ngOnInit() {
}
onDeselect() {
if(this.htmlCodeEagerly!=undefined)
{
this.htmlCode = this.htmlCodeEagerly.getCode();
}
if(this.jsCodeEagerly!=undefined)
{
this.jsCode = this.jsCodeEagerly.getCode();
}
if(this.cssCodeEagerly!=undefined)
{
this.cssCode = this.cssCodeEagerly.getCode();
}
}
runAllCodes() {
this.onDeselect();
console.log(this.htmlCode, this.cssCode, this.jsCode)
var html = this.htmlCode;
var css = this.cssCode;
var js = this.jsCode;
var code = "\n" +
"\n" +
"\n" +
" \n" +
" Editor \n" +
" \n" +
"\n" +
"\n";
code += "\n" + html;
code +=
"\n