You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular组件中Monaco Editor无法显示模型标记问题排查

Angular组件内Monaco Editor行内标记不显示问题

环境信息

  • angular 17.3.10
  • monaco-editor: ^0.52.2
  • ngx-monaco-editor-v2: ^19.0.2
  • editor.main.css 已正确加载

代码实现

模板

<ngx-monaco-editor  #editor style="max-width: 100%;" [(ngModel)]="viewSql" [options]="editorOptions" (onInit)="onEditorLoaded($event)" />

组件

import * as monaco from 'monaco-editor'; // 问题根源

public editorOptions: monaco.editor.IStandaloneEditorConstructionOptions = {
  language: 'sql',
  automaticLayout: true,
  theme: 'vs',
  readOnly: false,
  renderValidationDecorations: 'on', // 默认生效
};

private monacoEditor: monaco.editor.IStandaloneCodeEditor;

public onEditorLoaded(editor: monaco.editor.IStandaloneCodeEditor) {
  console.log('onEditorLoaded', editor);
  this.monacoEditor = editor;
  this.monacoEditor.updateOptions(this.editorOptions);
}

/** 本应生成标记但UI无任何下划线显示 */
handleValidationErrors(sqlErrors: Array<iSyntaxError>) {
  console.debug('handleValidationErrors', sqlErrors);
  if (!this.monacoEditor) return;

  const model = this.monacoEditor.getModel();

  if (sqlErrors.length) {
    // 转换错误为Monaco标记格式
    const markers = sqlErrors.map(error => ({
      message: error.OriginalMessage || error.Message,
      severity: monaco.MarkerSeverity.Error,
      startLineNumber: error.LineNumber, // LineNumber === 1
      startColumn: 1, //error.LinePosition || 1,
      endLineNumber: error.LineNumber, // LineNumber === 1
      endColumn: 100,
    } satisfies monaco.editor.IMarkerData));

    console.debug('markers', markers); // 日志输出正常
    // 设置标记
    monaco.editor.setModelMarkers(model, 'sql-validation', markers);
    // 滚动到第一个错误行
    this.monacoEditor.revealLineInCenter(sqlErrors[0].LineNumber);

  } else { // 无错误时清除标记
    console.warn("removeAllMarkers 'sql-validation'");
    monaco.editor.removeAllMarkers('sql-validation');
  }

  console.log('getModelMarkers',monaco.editor.getModelMarkers({owner: 'sql-validation'})); // 日志显示标记已添加
}

问题描述

日志明确显示标记已成功添加,但编辑器界面未显示预期的错误下划线(本应标记拼写错误的"select"),不确定问题出在代码、monaco-editor模块还是Angular封装器上,寻求解决思路。


解决思路

核心问题:Monaco实例不匹配

你直接通过import * as monaco from 'monaco-editor'导入的是全局独立实例,而ngx-monaco-editor-v2封装器内部维护了自己的Monaco实例,二者并非同一个上下文。这导致你调用monaco.editor.setModelMarkers时,标记被添加到了全局实例的模型中,而非当前编辑器正在使用的模型,因此UI无显示。

修复步骤

  1. 移除全局Monaco导入:删除import * as monaco from 'monaco-editor'这一行
  2. 通过封装器注入正确的Monaco实例:
    使用ngx-monaco-editor-v2提供的MONACO注入令牌获取与编辑器绑定的实例:
    import { MONACO } from 'ngx-monaco-editor-v2';
    import { Inject } from '@angular/core';
    
    constructor(@Inject(MONACO) private monaco: typeof monaco) {}
    
  3. 统一使用注入的实例:组件内所有操作Monaco的代码(如monaco.MarkerSeverity.Error、monaco.editor.setModelMarkers等)都使用这个注入的this.monaco对象。

额外排查点

  • 验证model有效性:确认this.monacoEditor.getModel()返回的是当前编辑器的活跃模型,而非null
  • 检查标记位置参数:确保行号、列号从1开始计数(Monaco的坐标规则),且范围覆盖目标文本
  • 强制编辑器刷新:设置标记后可尝试调用this.monacoEditor.layout()触发UI更新
  • 调整编辑器选项:将renderValidationDecorations设置为'always'测试是否生效

内容的提问来源于stack exchange,提问作者sritmak

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 15:55:56