如何在一个页面上有效地拥有许多只读的Monaco Diff Views?

Ole*_*Ole 7 javascript monaco-editor

我的理解是,Monaco针对编辑进行了优化,并且一次显示一个文件,使用固定大小的编辑器,它有自己的滚动条.

相反,我试图构建一个页面,其中多个文件的差异在彼此之下

  • 允许显示/隐藏每个文件,最多约100个文件
  • 隐藏未更改的文件部分(如果需要,允许将其显示为上下文)
  • 每个文件没有一个滚动条,但整个页面只有一个滚动条
  • 这些文件通常只能查看,但一次只能支持一个文件的编辑

我意识到这与摩纳哥的构建完全不同,但最终看起来似乎同样的视口和虚拟渲染技巧也适用,所以也许它在某种程度上可行?

我尝试为每个文件创建一个Monaco实例,但是在30个实例中开始变得非常缓慢.

一个非常丑陋的解决方法可能是拥有一个Monaco实例,连接所有文件,然后使用ViewZones,自定义行号提供程序和代码折叠提供程序来实现多个文件的印象.这听起来有点疯狂,还是真的有效?

还有其他建议吗?为什么IStandaloneDiffEditor 在名称中是独立的?这是否意味着还有另一种方法来创建更高效​​的差异编辑器?

Bha*_*ata 6

来自你的问题的Citate: 我尝试为每个文件创建一个Monaco实例,但是在30个实例中开始变得非常缓慢.

你的问题的解决方案

如你所说,性能低迷.这是因为您的服务器或可能是您的客户端没有足够的内存.您必须向服务器添加更多内存,或者可能是客户端以获得更多性能.因为我没有足够的信息,所以我不能说它是服务器或客户端.但这种方法效率不高.

来自您的问题的Citate: 为什么IStandaloneDiffEditor在名称中是独立的?这是否意味着还有另一种方法来创建更高效​​的差异编辑器?

什么都没有.在维基百科,我找到了独立的答案:

独立软件可以参考:

  • 可以脱机工作的计算机软件,即不一定需要网络连接才能运行.
  • 不属于某些捆绑软件的软件.
  • 作为单独的计算机进程运行的程序,而不是现有进程的附加组件.
  • 独立程序,一个不需要运行操作系统服务的程序.
  • 便携式应用程序,无需安装程序即可运行.

这意味着standalone与单个实例无关,您可以拥有此编辑器的多个实例.但是,您必须在计算机上拥有更多内存才能从此编辑器创建100个实例.这样做效率不高,因为你的内存中有100个大的JavaScript对象.

在其他服务上显示已更改文件之间的区别,它们DOM只使用对象或使用DOM对象+来自创建此对象的大型JavaScript对象的一个​​大实例,而不是来自大型JavaScript对象的其他100个大实例.

根据这个原则,在这种情况下,您可以使用我推荐的解决方案中的代码,并在后台仅使用此差异编辑器中的一个实例.然后你必须将所有100个文件一个接一个地放到这个实例中,然后从DOM对象后面的一个文件中复制:

  • <div class="editor original showUnused" ...
  • <div class="editor modified showUnused" ...

例如,您可以使用以下代码:

var diffPartContainars = document.querySelector('#container').querySelectorAll('.showUnused'),
    editorOriginalPartHTML,
    editorModifiedPartHTML;

for(var i = diffPartContainars.length; i--;)
{
    var obj = diffPartContainars[i],
        cln = obj.className;

    if(cln.indexOf('editor original') > -1)
    {
        obj.removeAttribute('style');
        editorOriginalPartHTML = obj.outerHTML;
    }
    if(cln.indexOf('editor modified') > -1)
    {
        obj.removeAttribute('style');
        editorModifiedPartHTML = obj.outerHTML;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后你必须从每个editorOriginalPartHTML和editorModifiedPartHTML中删除以下DOM对象:

  • <div class="invisible scrollbar horizontal" ...
  • <canvas class="decorationsOverviewRuler" ...
  • <div class="visible scrollbar vertical" ...

以及您不能使用的所有其他对象.当您添加你可以做到这一点editorOriginalPartHTML,并editorModifiedPartHTML给你的DOM.然后你可以从中添加一个div具有合适的对象width,height并且style="overflow:auto".还有一件事你可以做得更多:对于每个来自这些div对象的你可以添加一个onclick或者一个onmouseover监听器,然后用div差异编辑器实例替换这个对象视图.

在我看来,这只是提高效率的一种方式.祝好运!

推荐的有效解决方案

快速,舒适,高效的方式只有一个这个编辑器的实例,并在点击文件名时加载新的源代码,如下所示.

var diffEditor = null;
var filesContent =
{
    'SomeJavaScriptFile.js':
    {
        originalContent: 'alert("heLLo world!")',
        modifiedContent: 'alert("hello everyone!")',
        type: 'text/javascript'
    },
    'AnotherJavaScriptFile.js':
    {
        originalContent: 'function open(str)\n{\n\talert(str)\n}',
        modifiedContent: 'function output(value)\n{\n\tconsole.log(value)\n}',
        type: 'text/javascript'
    }
};

document.querySelector('#files').addEventListener('change', function(e)
{
    var fileName = this.options[this.selectedIndex].text,
        file = filesContent[fileName];

    openInDiffEditor(file);
});

function openInDiffEditor(file)
{
    if(!diffEditor)
        diffEditor = monaco.editor.createDiffEditor(document.querySelector('#container'));

    diffEditor.setModel({
        original: monaco.editor.createModel(file.originalContent, file.type),
        modified: monaco.editor.createModel(file.modifiedContent, file.type)
    });
}

//open the first file in select list:
var firstFileName = document.querySelector('#files').options[0].text;
openInDiffEditor(filesContent[firstFileName]);
Run Code Online (Sandbox Code Playgroud)
<p>Please select one file on the left list to see the file differences after changes.</p>
<select id="files" size="3">
    <option selected>SomeJavaScriptFile.js</option>
    <option>AnotherJavaScriptFile.js</option>
</select>

<div id="container" style="height:100%;"></div>
Run Code Online (Sandbox Code Playgroud)

您必须通过AJAX加载文件内容.但是如果您不了解如何加载它,那么问我,我会写它.

此推荐解决方案的屏幕截图

在此输入图像描述