在Web应用程序中使用Monaco编辑器。

11
我们有一个MVC Web应用程序,其中PowerShell被用作脚本引擎。目前,一个文本区域元素被用于脚本编辑,这证明是非常麻烦的。由于Microsoft发布了Monaco Editor,我们想知道是否可以将编辑器嵌入我们的应用程序作为小部件,以利用其语法检查和智能感知的功能。在查看了他们的文档后,并没有发现太多相关信息。这是可能的吗?或者Microsoft目前不支持在第三方应用程序中使用它?

1
是的,你可以...实际上他们在演示页面上就这么做了:https://microsoft.github.io/monaco-editor/ - Hackerman
1
完全没问题...你可以在自己的应用中使用它,只需要包含相关的js和css文件,就可以了。 - Hackerman
@Hackerman,感谢您的及时回复,但是我找不到相关的js和css文件在哪里获取。您能指引我吗? - ritchxu
我做到了 https://jsfiddle.net/robertrozas/r1b9hbhk/5/ - Hackerman
我只需要研究代码...进行一些替换以指向正确的命名空间并查看网络选项卡...我将提供完整的答案。 - Hackerman
显示剩余6条评论
1个回答

13

这是一个包含Monarc Editor在您网站上的解决方法,它仍然需要来自Microsoft的文件才能正常工作,但是,如果我们将这些文件下载到本地并修改baseUrl指向正确的文件夹,它应该可以工作:

基本HTML代码

<section class="try">
    <div class="container">
    <h3>Editor</h3>
        <div class="editor row">
            <div class="span3">                 
                <p>Colorizers are implemented using <a href="monarch.html"
                    target="_blank">Monarch</a>.</p>
            </div>
            <div class="span9">
                <div class="row">
                    <div class="span4">
                        <label class="control-label">Language</label>
                        <select class="language-picker"></select>
                    </div>
                    <div class="span4">
                        <label class="control-label">Theme</label>
                        <select class="theme-picker">
                            <option>Visual Studio</option>
                            <option>Visual Studio Dark</option>
                            <option>High Contrast Dark</option>
                        </select>
                    </div>
                </div>
                <div class="editor-frame">
                    <div class="loading editor" style="display: none;">
                        <div class="progress progress-striped active">
                            <div class="bar"></div>
                        </div>
                    </div>
                    <div id="editor"></div>
                </div>
            </div>
        </div>   
   </div>
</section>

JavaScript代码:

'use strict';
require.config({
    baseUrl: 'https://microsoft.github.io/monaco-editor/node_modules/monaco-editor/min/'
});


var editor = null,
    diffEditor = null;

$(document).ready(function() {
    require(['vs/editor/editor.main'], function() {
        var MODES = (function() {
            var modesIds = monaco.languages.getLanguages().map(function(lang) {
                return lang.id;
            });
            modesIds.sort();

            return modesIds.map(function(modeId) {
                return {
                    modeId: modeId,
                    sampleURL: 'https://microsoft.github.io/monaco-editor/index/samples/sample.' + modeId + '.txt'
                };
            });
        })();

        for (var i = 0; i < MODES.length; i++) {
            var o = document.createElement('option');
            o.textContent = MODES[i].modeId;
            $(".language-picker").append(o);
        }
        $(".language-picker").change(function() {
            loadSample(MODES[this.selectedIndex]);
        });
        $('.language-picker').selectpicker({
            size: 10
        });
        loadSample(MODES[0]);

        $(".theme-picker").change(function() {
            changeTheme(this.selectedIndex);
        });
        $('.theme-picker').selectpicker({
            size: 3
        });

        loadDiffSample();

        $('#inline-diff-checkbox').change(function() {
            diffEditor.updateOptions({
                renderSideBySide: !$(this).is(':checked')
            });
        });
    });

    window.onresize = function() {
        if (editor) {
            editor.layout();
        }
        if (diffEditor) {
            diffEditor.layout();
        }
    };
});

function loadSample(mode) {
    $.ajax({
        type: 'GET',
        url: mode.sampleURL,
        dataType: 'text',
        beforeSend: function() {
            $('.loading.editor').show();
        },
        error: function() {
            if (editor) {
                if (editor.getModel()) {
                    editor.getModel().dispose();
                }
                editor.dispose();
                editor = null;
            }
            $('.loading.editor').fadeOut({
                duration: 200
            });
            $('#editor').empty();
            $('#editor').append('<p class="alert alert-error">Failed to load ' + mode.modeId + ' sample</p>');
        }
    }).done(function(data) {
        if (!editor) {
            $('#editor').empty();
            editor = monaco.editor.create(document.getElementById('editor'), {
                model: null,
            });
        }

        var oldModel = editor.getModel();
        var newModel = monaco.editor.createModel(data, mode.modeId);
        editor.setModel(newModel);
        if (oldModel) {
            oldModel.dispose();
        }
        $('.loading.editor').fadeOut({
            duration: 300
        });
    });
}

function loadDiffSample() {

    var onError = function() {
        $('.loading.diff-editor').fadeOut({
            duration: 200
        });
        $('#diff-editor').append('<p class="alert alert-error">Failed to load diff editor sample</p>');
    };

    $('.loading.diff-editor').show();

    var lhsData = null,
        rhsData = null,
        jsMode = null;

    $.ajax({
        type: 'GET',
        url: 'https://microsoft.github.io/monaco-editor/index/samples/diff.lhs.txt',
        dataType: 'text',
        error: onError
    }).done(function(data) {
        lhsData = data;
        onProgress();
    });

    $.ajax({
        type: 'GET',
        url: 'https://microsoft.github.io/monaco-editor/index/samples/diff.rhs.txt',
        dataType: 'text',
        error: onError
    }).done(function(data) {
        rhsData = data;
        onProgress();
    });

    function onProgress() {
        if (lhsData && rhsData) {
            diffEditor = monaco.editor.createDiffEditor(document.getElementById('diff-editor'), {
                enableSplitViewResizing: false
            });

            var lhsModel = monaco.editor.createModel(lhsData, 'text/javascript');
            var rhsModel = monaco.editor.createModel(rhsData, 'text/javascript');

            diffEditor.setModel({
                original: lhsModel,
                modified: rhsModel
            });

            $('.loading.diff-editor').fadeOut({
                duration: 300
            });
        }
    }
}

function changeTheme(theme) {
    var newTheme = (theme === 1 ? 'vs-dark' : (theme === 0 ? 'vs' : 'hc-black'));
    if (editor) {
        editor.updateOptions({
            'theme': newTheme
        });
    }
    if (diffEditor) {
        diffEditor.updateOptions({
            'theme': newTheme
        });
    }
}

可工作的代码示例: https://jsfiddle.net/robertrozas/r1b9hbhk/


你知道为什么当我在一个干净的MVC应用程序中尝试这个解决方法时,它可以工作,但当它被用于我的真实项目时,会出现“Uncaught ReferenceError:require未定义”的错误吗?此外,我注意到,如果您将jsfiddle中jquery引用的源替换为[link](https://code.jquery.com/jquery-1.9.1.min.js),它将生成错误。这是我的项目(jquery 2.2.1)和干净的MVC应用程序(jquery 1.9.1)之间的区别。 - ritchxu
如果您查看Monaco Editor演示,它们使用Jquery 1.9.1,因此编辑器可能无法与更高版本配合使用... - Hackerman
@Hackerman,我认为那个演示中的Intellisense没有起作用,我相信该人已经请求了它。 - c-sharp-and-swiftui-devni
1
@rogue39nin 这个演示已经四年了...而且原帖的提问者已经接受了答案。 - Hackerman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接