사용자 도구

사이트 도구


monaco-editor

차이

문서의 선택한 두 판 사이의 차이를 보여줍니다.

차이 보기로 링크

양쪽 이전 판이전 판
다음 판
이전 판
monaco-editor [2023/05/05 01:39] – [Angular App] taekgumonaco-editor [2025/04/15 10:05] (현재) – 바깥 편집 127.0.0.1
줄 1: 줄 1:
 +====== Microsoft Monaco Editor ======
  
 +  * [[study:monaco_editor|Microsoft Monaco Editor]]
 +
 +===== Angular 자료교환 =====
 +
 +  이것을 별도참조 atularen/ngx-monaco-editor.
 +
 +===== Angular App =====
 +
 +<code bash>
 +npm install monaco-editor
 +</code>
 +
 +<code json angular.json>
 +"assets": [
 +              ...
 +              {
 +                "glob": "**/*",
 +                "input": "node_modules/monaco-editor",
 +                "output": "assets/monaco-editor"
 +              }
 +            ],
 +</code>
 +
 +<code javascript monaco-editor-service.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();
 +    }
 +  }
 +}
 +</code>
 +
 +Now call monacoEditorService.load(), as soon as you need the editor (in my case it's called in app.component.ts in the constructor, to make the editor always available and already preload it).
 +
 +Now, you can create editors as you please, but make sure to not create them, before Monaco is loaded yet. Like this:
 +
 +<code javascript monaco-editor.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();
 +  }
 +</code>
 +There are most probably more elegant solutions than a boolean flag and this subject.
 +
 +Make sure, there is a div in the component, like this:
 +
 +<code html monaco-editor.component.html>
 +  <div class="editor-container" #editorContainer></div>
 +</code>