首页 > 解决方案 > Javascript 不会更新 blazor 组件的值

问题描述

我有一个问题,我想将 CK 编辑器的值传递给 Monaco 编辑器。我可以从摩纳哥获得价值,但不能反过来。我也可以在调试时看到值更新,但它似乎无法以某种方式工作。

所以我想要的是当我在 CK 编辑器中键入内容并按下按钮切换到 Monaco 以在 Monaco 编辑器中获得 CK 编辑器的值

这是 javasciprt :

function CkEditor(id, readonly, dotNetReference) {
    CKEDITOR.replace(id, {
        customConfig: '../ckeditor/config.js'
    });


    var editor = CKEDITOR.instances[id];
    var editorId = editor.id;
    var monacoEditor = document.getElementById("monaco_" + editor.name);
    // Hide toolbar while loading
    editor.on('loaded', () => {
        document.getElementById(editorId + '_top').style.display = 'none';
    });

    editor.on('instanceReady', () => {
        EnableCkEditor(id, readonly);
    });

    editor.on('change', () => {
        var data = editor.getData();
        if (data === '') {
            data = null;
        }
        dotNetReference.invokeMethodAsync('EditorHasChanged', data);
    });

    editor.on('focus', (id) => {
        editor.focusManager.focus();
        document.getElementById(editorId + '_top').style.display = 'block';
        editor.on('afterCommandExec', (event) => {
            var commandName = event.data.name;
            if (commandName === 'enableMonaco') {
                if (monacoIsEnabled === false) {
                    document.getElementById(editorId + '_contents').style.display = 'none';
                    monacoEditor.classList.remove('monaco-wrapper');
                    monacoIsEnabled = true;
                }
                else {
                    editor.setData(monacoEditorData.value);
                    document.getElementById(editorId + '_contents').style.display = 'block';
                    monacoEditor.classList.add('monaco-wrapper');
                    monacoIsEnabled = false;
                }
            }
        });
    });

    editor.on('blur', () => {
        if (!monacoIsEnabled) {
            document.getElementById(editorId + '_top').style.display = 'none';
        }
    });
}

function setCkEditorValue(value) {
    monacoEditorData.value = value;
}

function CkEditorDestroy(id) {
    var editor = CKEDITOR.instances[id];
    editor.destroy();
    delete editor;
}

function EnableCkEditor(id, readonly) {
    var editor = CKEDITOR.instances[id];
    if (editor) {
        var editId = editor.id;
        var editorBody = document.getElementById(editId + '_contents');
        if (readonly === true) {
            editorBody.classList.add('disabled_class');
        }
        else {
            editorBody.classList.remove('disabled_class');
        }
    }
}

这是在 Monaco 和 CK 之间切换的组件:

@inherits MarkupEditorComponent
@Value
<div id="wrapper">
    <div class="ck-editor-wrapper">
        <CkEditor Value="@Value" ValueChanged="@ValueChanged" Readonly="@Readonly" id="@Id"/>
    </div>

    <div class="monaco-wrapper" id="monaco_@Id">
        <CodeEditor Value="@Value" ValueChanged="@ValueChanged" Readonly="@Readonly"/>
    </div>
</div>

这是 CKEditor.razor

@inherits CkEditorComponent

<div id="wrapper">
    <div class="ck-editor-wrapper">
        <textarea @attributes="AdditionalAttributes"
                  id="@Id"
                  class="CssClass"
                  value="@Value"></textarea>
    </div>
</div>

最后是 CKEditor.razor.cs

    public class CkEditorComponent : BaseComponent
    {
        string _id = $"CKEditor{Guid.NewGuid().ToString().ToLower().Replace("-", string.Empty)}";

        [Parameter]
        public string Value { get; set; }

        [Parameter]
        public EventCallback<string> ValueChanged { get; set; }

        [Parameter]
        public bool Readonly { get; set; }

        [Parameter]
        public IReadOnlyDictionary<string, object> AdditionalAttributes { get; set; }

        [Parameter]
        public string Id
        {
            get => _id;
            set => _id = value;
        }


        protected override async Task OnInitializedAsync()
        {
            await EditorHasChanged(Value);
        }

        protected override async Task OnParametersSetAsync()
        {
            await EnableEditor(Readonly);
            await base.OnParametersSetAsync();
        }

        protected override async Task OnAfterRenderAsync(bool firstRender)
        {
            if (firstRender)
            {
                await JsRuntime.InvokeVoidAsync("CkEditor", Id, Readonly, DotNetObjectReference.Create(this));
            }
        }

        [JSInvokable(nameof(EditorHasChanged))]
        public Task EditorHasChanged(string data)
        {
            Value = data;
            ValueChanged.InvokeAsync(data);
            return Task.CompletedTask;
        }

        protected override void Dispose(bool disposing)
        {
            JsRuntime.InvokeVoidAsync("CkEditorDestroy", Id);
            base.Dispose(disposing);
        }

        private async Task EnableEditor(bool enabled)
        {
            await JsRuntime.InvokeVoidAsync("EnableCkEditor", Id, enabled);
        }
    }

标签: javascriptc#blazor

解决方案


您可能需要调用StateHasChanged()inside EditorHasChanged(string data)这里有一个类似的问题。


推荐阅读