CodeMirror 绑定在 Blazor 应用程序中不起作用

rag*_*jan 5 codemirror blazor blazor-server-side

我正在开发使用代码编辑器的 Blazor Server 应用程序。对于代码编辑器,我使用 CodeMirror。文本区域在 Blazor 页面上呈现良好,但数据绑定不适用于相应的 C# 字段。

Blazor 页面截图

我的_Host.cshtml文件如下:

@page "/"
@namespace BlazorApp1.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@{
    Layout = null;
}

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>BlazorApp1</title>
    <base href="~/" />
    <link rel="stylesheet" href="css/bootstrap/bootstrap.min.css" />
    <link href="css/site.css" rel="stylesheet" />

    <script src="~/codemirror/codemirror.js"></script>
    <link rel="stylesheet" href="~/codemirror/codemirror.css">

    <script src="~/codemirror/mode/clike.js"></script>
    <script src="~/codemirror/addon/display/fullscreen.js"></script>
    <link rel="stylesheet" href="~/codemirror/addon/display/fullscreen.css">
    <link rel="stylesheet" href="/codemirror/theme/monokai.css">
    <script>
        function loadCodeEditor() {
            var codemirrorEditor = CodeMirror.fromTextArea(document.getElementById('codearea'), {
                lineNumbers: true,
                styleActiveLine: true,
                matchBrackets: true,
                mode: "text/x-csharp",
                theme: "monokai",
                extraKeys: {
                    "F11": function (cm) {
                        cm.setOption("fullScreen", !cm.getOption("fullScreen"));
                    },
                    "Esc": function (cm) {
                        if (cm.getOption("fullScreen")) cm.setOption("fullScreen", false);
                    }
                }
            });
            codemirrorEditor.setSize(900, 300);
        }
    </script>

</head>
<body>
    <app>
        <component type="typeof(App)" render-mode="ServerPrerendered" />
    </app>

    <div id="blazor-error-ui">
        <environment include="Staging,Production">
            An error has occurred. This application may no longer respond until reloaded.
        </environment>
        <environment include="Development">
            An unhandled exception has occurred. See browser dev tools for details.
        </environment>
        <a href="" class="reload">Reload</a>
        <a class="dismiss"></a>
    </div>

    <script src="_framework/blazor.server.js"></script>
</body>
</html>

Run Code Online (Sandbox Code Playgroud)

而razor页面代码如下:

@page "/"
@inject IJSRuntime JSRuntime;

<h1>Hello, world!</h1>

Welcome to your new app.

<textarea id="codearea" rows="20" @bind="UserCodeInput" @bind:event="oninput" style="height:100px;"></textarea>

<SurveyPrompt Title="How is Blazor working for you?" />

Input Code: @UserCodeInput

@code{

    public string UserCodeInput { get; set; }

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            await JSRuntime.InvokeVoidAsync("loadCodeEditor");
        }
    }
}

Run Code Online (Sandbox Code Playgroud)

如果我从textarea属性中删除id="codearea"并注释掉 JSInterop 方法调用,则绑定工作正常。

请建议如何修复与 CodeMirror 的绑定。

rag*_*jan 5

最后,我能够使用 CodeMirror 编辑器绑定该字段。感谢以下主题:

当我使用 CodeMirror 编辑 TextArea 中的代码时,如何使用 js 或 jQuery 将其反映到另一个文本区域中

如何使用 JavaScript 更新 Blazor 中的 C# 值?

我必须在调用 JavaScript 函数时传递 DotNet 对象引用,然后在 JavaScript 函数中使用 CodeMirror 的 onchange 事件来调用 C# 方法并传递代码编辑器的值。

以下是包含工作代码的更新文件:

_Host.cshtml

@page "/"
@namespace BlazorApp1.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@{
    Layout = null;
}

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>BlazorApp1</title>
    <base href="~/" />
    <link rel="stylesheet" href="css/bootstrap/bootstrap.min.css" />
    <link href="css/site.css" rel="stylesheet" />

    <script src="~/codemirror/codemirror.js"></script>
    <link rel="stylesheet" href="~/codemirror/codemirror.css">

    <script src="~/codemirror/mode/clike.js"></script>
    <script src="~/codemirror/addon/display/fullscreen.js"></script>
    <link rel="stylesheet" href="~/codemirror/addon/display/fullscreen.css">
    <link rel="stylesheet" href="/codemirror/theme/cobalt.css">
    <link rel="stylesheet" href="/codemirror/theme/monokai.css">
    

</head>
<body>
    <app>
        <component type="typeof(App)" render-mode="ServerPrerendered" />
    </app>



    <div id="blazor-error-ui">
        <environment include="Staging,Production">
            An error has occurred. This application may no longer respond until reloaded.
        </environment>
        <environment include="Development">
            An unhandled exception has occurred. See browser dev tools for details.
        </environment>
        <a href="" class="reload">Reload</a>
        <a class="dismiss"></a>
    </div>

    <script src="_framework/blazor.server.js"></script>
    <script>
        function loadCodeEditor(dontNetObjRef) {
                var codemirrorEditor = CodeMirror.fromTextArea(document.getElementById('codearea'), {
                    lineNumbers: true,
                    styleActiveLine: true,
                    matchBrackets: true,
                    mode: "text/x-csharp",
                    theme: "monokai",
                    extraKeys: {
                        "F11": function (cm) {
                            cm.setOption("fullScreen", !cm.getOption("fullScreen"));
                        },
                        "Esc": function (cm) {
                            if (cm.getOption("fullScreen")) cm.setOption("fullScreen", false);
                        }
                    }
                });
            codemirrorEditor.setSize(900, 500);
            codemirrorEditor.on("change", editor => {
                dontNetObjRef.invokeMethodAsync("UpdateField", editor.getValue());
                console.log(editor.getValue());
            });
            }
    </script>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)

剃须刀页面:

@page "/"
@inject IJSRuntime JSRuntime;

<h1>Hello, world!</h1>

Welcome to your new app.

<textarea id="codearea"></textarea>

<SurveyPrompt Title="How is Blazor working for you?" />

<br />
<br />

Input Code: @UserCodeInput

@code{

    public string UserCodeInput { get; set; }

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {

            await JSRuntime.InvokeVoidAsync("loadCodeEditor", DotNetObjectReference.Create(this));
        }
    }

    [JSInvokable("UpdateField")]
    public Task UpdateField(string codeValue)
    {
        UserCodeInput = codeValue;
        StateHasChanged();
        return Task.CompletedTask;
    }
}

Run Code Online (Sandbox Code Playgroud)