这就是我解决这个问题的方法,很大程度上受到 atularen/ngx-monaco-editor 的启发。但我也不想依赖这种依赖。可能有更好的解决方案。
npm install monaco-editor
角度.json:
"assets": [
...
{
"glob": "**/*",
"input": "node_modules/monaco-editor",
"output": "assets/monaco-editor"
}
],
摩纳哥编辑服务.ts:
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs';
@Injectable({
providedIn: 'root',
})
export class MonacoEditorService {
loaded: boolean = false;
public loadingFinished: Subject<void> = new Subject<void>();
constructor() {}
private finishLoading() {
this.loaded = true;
this.loadingFinished.next();
}
public load() {
// load the assets
const baseUrl = './assets' + '/monaco-editor/min/vs';
if (typeof (<any>window).monaco === 'object') {
this.finishLoading();
return;
}
const onGotAmdLoader: any = () => {
// load Monaco
(<any>window).require.config({ paths: { vs: `${baseUrl}` } });
(<any>window).require([`vs/editor/editor.main`], () => {
this.finishLoading();
});
};
// load AMD loader, if necessary
if (!(<any>window).require) {
const loaderScript: HTMLScriptElement = document.createElement('script');
loaderScript.type = 'text/javascript';
loaderScript.src = `${baseUrl}/loader.js`;
loaderScript.addEventListener('load', onGotAmdLoader);
document.body.appendChild(loaderScript);
} else {
onGotAmdLoader();
}
}
}
现在打电话摩纳哥编辑服务.load(),只要您需要编辑器(在我的例子中,它在构造函数中的 app.component.ts 中调用,以使编辑器始终可用并已预加载)。
现在,您可以根据需要创建编辑器,但请确保在加载 Monaco 之前不要创建它们。像这样:
摩纳哥编辑器.component.ts
import ...
declare var monaco: any;
@Component({
selector: 'app-monaco-editor',
templateUrl: './monaco-editor.component.html',
styleUrls: ['./monaco-editor.component.scss'],
})
export class MonacoEditorComponent implements OnInit, OnDestroy, AfterViewInit {
public _editor: any;
@ViewChild('editorContainer', { static: true }) _editorContainer: ElementRef;
private initMonaco(): void {
if(!this.monacoEditorService.loaded) {
this.monacoEditorService.loadingFinished.pipe(first()).subscribe(() => {
this.initMonaco();
});
return;
}
this._editor = monaco.editor.create(
this._editorContainer.nativeElement,
options
);
}
ngAfterViewInit(): void {
this.initMonaco();
}
很可能有比布尔标志和这个主题更优雅的解决方案。
摩纳哥-editor.component.html
确保组件中有一个 div,如下所示:
<div class="editor-container" #editorContainer></div>