簡體   English   中英

在 Slate.js editor.apply(operation) 中沒有正確應用“split_node”操作

[英]In Slate.js editor.apply(operation) is not applying "split_node" operations correctly

我正在設計一個類似 google-doc 的協作工具,使用最新的 React + Slate 作為前端,后端使用 Flask。 我在 React 中使用 socket-io 和在 Python 中使用 flask_socketio 來發出和收聽來自其他合作者的內容。 反應應用程序代碼:

const RichTextExample = props => {
  const [value, setValue] = useState(props.currentEditor);
  const editor = useMemo(() => withHistory(withReact(createEditor())), []);
  const id = useRef(`${Date.now()}`);
  const remote = useRef(false);
  const socketchange = useRef(false);

  useEffect(() => {
    socket.on("new-remote-operations", ({ editorId, ops, doc_id }) => {
      if (id.current !== editorId && doc_id === props.document.doc_id) {
        remote.current = true;
        JSON.parse(ops).forEach(op => {
          console.log("LISTEN: applying op", op);
          editor.apply(op);
        });
        remote.current = false;
        console.log('value is ', value);
        socketchange.current = true; //variable to track socket changes in editor via operations
      }
    });}, [])
    return(
    <Slate
        editor={editor}
        value={value}
        onChange={value => {
          setValue(value);
          const ops = editor.operations
          .filter(o => {
            if (o) {
              return o.type !== "set_selection" && o.type !== "set_value";
            }
            return false;
          });
          if (ops.length && !remote.current && !socketchange.current) {
            console.log("EMIT: Editor operations are ", ops);
            socket.emit("new-operations", {
              editorId: id.current,
              ops: JSON.stringify(ops),
              doc_id: props.document.doc_id
            });
          }
          socketchange.current = false;
        }}
      >

套接字的 Python 代碼很簡單:

app = Flask(__name__)
db_name = 'userdoc.db'
app.config['SECRET_KEY'] = 'secret-key'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///'+db_name
socketio = SocketIO(app, cors_allowed_origins="*")
@socketio.on('new-operations', namespace='/')
def operations(data):
    print('operations listened...1/2/3..')
    emit('new-remote-operations', data, broadcast=True, include_self=False)

問題

當 split_node 作為 socket.on() 中的一種操作類型傳遞時, editor.apply(op) 不會像它想象的那樣應用它。 請幫我解決這個問題。

因此,我得到以下兩種情況: 情況1

在此處輸入圖片說明 在此處輸入圖片說明

我認為您面臨的問題是因為您發送了一批不應逐個應用的操作。

像您通過按enter生成的那樣的split_node操作實際上會拆分所有嵌套節點,直到它到達葉子,並移動一些節點。

具體來說,一個split_node實際上是2-3個操作,不能單獨應用。 例如,如果您應用第一個,這將拆分文本節點,並最終得到兩個共享相同屬性的Text Slate 將規范化它們並盡快重新合並它們,在您的情況下,這發生在每個editor.apply(op)

我認為這里的解決方案只是將整個循環包裝在withoutNormalizing方法中。 它會阻止 Slate 在操作之間規范化文檔。

對於 Slate <= 0.47

editor.withoutNormalizing(() => {
  JSON.parse(ops).forEach(op => {
    editor.apply(op);
  });
})

對於 Slate >= 0.5

Editor.withoutNormalizing(editor, () => {
  JSON.parse(ops).forEach(op => {
    editor.apply(op);
  });
})

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM