JavaScript无法更新Blazor组件值:CKEditor内容无法同步到Monaco编辑器
问题根因
- 切换到Monaco编辑器的逻辑仅修改了容器显隐样式,没有将CKEditor的最新值同步到Monaco实例和对应的绑定数据源
- Monaco为纯JS实现的组件,Blazor侧的
Value参数更新不会自动同步到已初始化的Monaco实例中,缺少主动同步的逻辑
修复步骤
步骤1:修改切换编辑器时的同步逻辑
修改CkEditor函数中enableMonaco命令的处理分支,切换到Monaco时主动同步最新值:
editor.on('afterCommandExec', (event) => { var commandName = event.data.name; if (commandName === 'enableMonaco') { if (monacoIsEnabled === false) { // 新增逻辑:同步CKEditor最新值到Monaco const ckCurrentValue = editor.getData() || ''; monacoEditorData.value = ckCurrentValue; // 替换为你实际存储的Monaco实例变量,调用setValue更新显示 window.monacoInstance.setValue(ckCurrentValue); 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; } } });
步骤2:(可选)实时同步CKEditor值到Monaco数据源
如果需要实时同步而非切换时才同步,可以在CKEditor的change事件中新增同步逻辑:
editor.on('change', () => { var data = editor.getData(); if (data === '') { data = null; } // 新增:实时同步到Monaco数据源 monacoEditorData.value = data; dotNetReference.invokeMethodAsync('EditorHasChanged', data); });
步骤3:补全Monaco侧的参数同步逻辑
在你的CodeEditor组件(Monaco封装组件)中新增参数变化监听,Blazor侧Value更新时主动通知JS更新Monaco实例:
- 首先在
CodeEditor.razor.cs中新增参数变化处理:
private string _oldValue; private bool _isInitialized; protected override async Task OnAfterRenderAsync(bool firstRender) { if (firstRender) { // 原有初始化逻辑 _isInitialized = true; _oldValue = Value; } } protected override async Task OnParametersSetAsync() { if (_isInitialized && Value != _oldValue) { _oldValue = Value; // 调用JS更新Monaco值 await JsRuntime.InvokeVoidAsync("updateMonacoValue", $"monaco_{Id}", Value); } }
- 新增对应的JS方法:
// 全局存储Monaco实例,初始化时写入,key为monaco容器id window.monacoInstances = window.monacoInstances || {}; function updateMonacoValue(monacoId, value) { const instance = window.monacoInstances[monacoId]; if (instance && instance.getValue() !== value) { // 暂停事件监听避免循环触发更新 const originalChangeHandler = instance.onDidChangeModelContent; instance.onDidChangeModelContent = () => {}; instance.setValue(value); // 恢复事件监听 setTimeout(() => { instance.onDidChangeModelContent = originalChangeHandler; }, 0); } }
注意事项
- 确保
monacoEditorData变量的作用域可覆盖到CkEditor函数内 - 初始化Monaco实例时,将实例存入
window.monacoInstances全局对象中,key对应Monaco容器的id - 赋值时临时关闭Monaco的change事件监听,避免和CKEditor的更新逻辑形成死循环
内容的提问来源于stack exchange,提问作者Lucifenroo
相关产品推荐
相关产品推荐

