javascript - 如何有效地在一页上有许多只读的摩纳哥差异视图?
问题描述
我的理解是,摩纳哥针对编辑进行了优化,一次只显示一个文件,具有固定大小的编辑器,它有自己的滚动条。
相反,我正在尝试构建一个页面,其中多个文件的差异位于彼此下方
- 允许显示/隐藏每个文件,最多 100 个文件
- 隐藏文件中未更改的部分(如果需要,允许将它们显示为上下文)
- 每个文件没有一个滚动条,而是整个页面都有一个滚动条
- 这些文件通常仅供查看,但应支持一次编辑一个文件
我意识到这与摩纳哥的建造目的大相径庭,但最终似乎相同的视口和虚拟渲染技巧将适用,所以也许它是可能的?
我尝试为每个文件创建一个 Monaco 实例,但是大约 30 个实例开始变得非常缓慢。
一个非常难看的解决方法可能是拥有一个 Monaco 实例,连接所有文件,然后使用 ViewZones、自定义行号提供程序和代码折叠提供程序来实现多个文件的印象。这听起来很疯狂,还是真的可行?
还有其他建议吗?为什么 IStandaloneDiffEditor 名称中有独立?这是否意味着还有另一种方法可以创建许多更有效的差异编辑器?
解决方案
引用您的问题: 我尝试为每个文件创建一个 Monaco 实例,但是在 30 个实例左右开始变得非常缓慢。
您的问题的解决方案
正如你提到的,性能很慢。这是因为您的服务器或可能是您的客户端没有足够的内存。您必须向服务器添加更多内存,或者可能向客户端添加更多内存以获得更高的性能。因为我没有足够的信息我不能说它是服务器还是客户端。但这种方法效率不高。
引用您的问题: 为什么 IStandaloneDiffEditor 的名称中有独立?这是否意味着还有另一种方法可以创建许多更有效的差异编辑器?
从中一无所获。在维基百科中,我找到了独立意味着什么的答案:
独立软件可以指:
- 可以离线工作的计算机软件,即不一定需要网络连接才能运行。
- 不属于某些捆绑软件的软件。
- 作为单独的计算机进程运行的程序,而不是现有进程的附加组件。
- 独立程序,不需要操作系统服务即可运行的程序。
- 可移植的应用程序,无需安装程序即可运行。
这意味着独立与单个实例无关,您可以拥有此编辑器的多个实例。但是您必须在计算机上拥有更多内存才能从该编辑器创建 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;
}
}
然后您必须从每个 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]);
<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>
您必须通过 AJAX 加载文件内容。但是,如果您不明白如何加载它,请问我,我会写的。
此推荐解决方案的屏幕截图
推荐阅读
- java - 如何在 Java 中传递通过包对象从 Scala 定义的隐式 val
- php - 使用请求将 PHP API POST 调用转换为 Python
- kubernetes - kubelet.service:主进程退出,code=exited,status=255/n/a
- python - 使用 pymnet 固定多路网络图中节点的位置
- android - React Native 应用程序 - 在 Android 8 真实设备上启动时崩溃/关闭
- python - PyQt4 将 LineEdit 拉伸到窗口宽度
- c# - 如何处理flurl中的错误请求异常
- android - Android JobScheduler 实现
- scala - 使用 Spark 的不同值的增量过滤器 DataFrame
- firebase - 如何使用 Firebase 适配器从单个孩子那里获取键和值