如何初始化绑定Yjs的CodeMirror编辑器值且不影响POST请求
Let me break down your problem and walk you through the fixes step by step:
What's Going Wrong
Direct
setValuedoesn't work: You're trying to set the editor value witheditor.setValue(content), but Yjs'WebsocketProvideris syncing an emptyyTextfrom your server, which overwrites the value you set manually. Since you're using Yjs for collaboration, the editor's content is controlled by theyTextdocument, not direct editor calls.Chained call breaks everything: When you do
const editor = CodeMirror(...).setValue(content), you're assigningundefinedtoeditor—because CodeMirror'ssetValuemethod doesn't return the editor instance. That's why you get theeditor is undefinederror when trying to accesseditor.getValue()on submit.
The Fix
Instead of fighting against Yjs' sync logic, work with it. We'll use Yjs' yText to set the initial value, properly bind it to the editor, and adjust your submit logic to pull content from the synced yText instead of the editor directly.
Here's the revised JavaScript code:
/* eslint-env browser */ import * as Y from 'yjs' import { WebsocketProvider } from 'y-websocket' import { CodeMirrorBinding } from 'y-codemirror' import CodeMirror from 'codemirror' import 'codemirror/mode/clike/clike.js' window.addEventListener('load', () => { const ydoc = new Y.Doc() const provider = new WebsocketProvider( `${location.protocol === 'http:' ? 'ws:' : 'wss:'}${location.host}`, 'codemirror', ydoc ) const yText = ydoc.getText('codemirror') const editorContainer = document.createElement('div') editorContainer.setAttribute('id', 'editor') document.body.insertBefore(editorContainer, null) // Grab your initial content from the hidden textarea const initialContent = document.getElementById("content").value // Create the CodeMirror instance first (no chained calls!) const editor = CodeMirror(editorContainer, { mode: 'text/x-java', lineNumbers: true }) // Bind Yjs' yText to the editor—this syncs content both ways const binding = new CodeMirrorBinding(yText, editor) // Only set initial content if yText is empty (avoids overwriting collaborative changes) if (yText.length === 0 && initialContent) { yText.insert(0, initialContent) } // Update your submit logic to use yText instead of editor.getValue() document.getElementById("form").onsubmit = function(evt){ document.getElementById("editortext").value = yText.toString(); } })
Key Changes Explained
- No more chained
setValue: We create the editor instance first, then handle content population via Yjs (no need for manualsetValueanymore). - Proper
CodeMirrorBindingsetup: This bindsyTextto the editor, so any changes toyText(including our initial insert) automatically sync to the editor, and vice versa. - Initial content via
yText: We check ifyTextis empty before inserting the initial content—this ensures we don't overwrite any existing collaborative content from the server. - Submit uses
yText.toString(): This guarantees we're sending the latest synced content, not just the editor's local state.
Why This Works
Yjs is designed to be the single source of truth for collaborative content. By using yText to manage the editor's value, we let Yjs handle syncing both the initial load and any real-time changes. Your backend POST logic stays exactly the same—you're still populating editortext on submit, just pulling from the synced Yjs document instead of the editor directly.
内容的提问来源于stack exchange,提问作者Notemaster

