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

Monaco编辑器报错:lineNumber值非法,动态修改内容时如何处理装饰?

Monaco编辑器0.38版本装饰报错解决方案

问题原因

从0.30升级到0.38后,Monaco的装饰管理逻辑有调整,当动态修改内容导致行数减少时,若装饰操作与内容更新的时序不当,或使用的装饰API未适配新版本的模型同步逻辑,就会出现非法行号的报错——即使调用了清空装饰的代码,也可能因为旧装饰未完全清理、新装饰引用了已不存在的行号而触发错误。

正确的装饰管理方式

1. 改用createDecorationsCollection管理装饰

放弃deltaDecorations,使用createDecorationsCollection创建可观察的装饰集合,它能自动适配模型内容的变化,避免手动管理装饰ID的时序问题。

初始化装饰集合

// 类内属性声明
private decorationCollection: monaco.editor.IEditorDecorationsCollection | null = null;

// 编辑器初始化完成后创建集合
this.decorationCollection = this.editor!.createDecorationsCollection();

清空装饰

this.decorationCollection!.set([]);

更新内容并添加新装饰

// 步骤1:先清空现有装饰
this.decorationCollection!.set([]);

// 步骤2:更新编辑器内容
this.editor!.setValue(newContent);

// 步骤3:确保内容更新后,再添加新装饰(校验行号合法性)
const model = this.editor!.getModel();
if (!model) return;

const maxLine = model.getLineCount();
// 仅当错误行号在合法范围内时添加装饰
if (errorLine <= maxLine && errorLine >= 1) {
  const newDecorations: monaco.editor.IModelDeltaDecoration[] = [
    {
      range: new monaco.Range(errorLine, 1, errorLine, model.getLineMaxColumn(errorLine)),
      options: {
        className: 'custom-error-decoration',
        // 其他装饰配置
      }
    }
  ];
  this.decorationCollection!.set(newDecorations);
}

2. 若坚持使用deltaDecorations

需严格保证时序和行号合法性:

  • 每次更新内容前,必须调用deltaDecorations清空所有装饰,且确保返回的新装饰ID被正确保存。
  • 内容更新完成后,重新计算装饰的行号(必须小于等于当前模型的总行数),再调用deltaDecorations添加新装饰。
// 清空装饰
this.decorations = this.editor!.deltaDecorations(this.decorations, []);

// 更新内容
this.editor!.setValue(newContent);

// 添加新装饰前校验行号
const model = this.editor!.getModel();
if (!model) return;
const maxLine = model.getLineCount();
if (errorLine > maxLine) return;

const newDecorations = [
  {
    range: new monaco.Range(errorLine, 1, errorLine, model.getLineMaxColumn(errorLine)),
    options: { className: 'error-line' }
  }
];
this.decorations = this.editor!.deltaDecorations(this.decorations, newDecorations);

关键注意事项

  • 任何时候添加装饰前,都必须校验目标行号是否在当前模型的有效行数范围内(1 <= lineNumber <= model.getLineCount())。
  • 不要同时混用deltaDecorations和createDecorationsCollection,避免装饰管理冲突。
  • 若遇到异步渲染导致的延迟,可通过editor.onDidChangeModelContent事件监听内容更新完成,再触发装饰添加:
this.editor!.onDidChangeModelContent(() => {
  // 内容更新完成后执行装饰逻辑
  this.updateDecorations();
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 00:15:02