【问题标题】:Is it possible to serialize an Ace Session object?是否可以序列化 Ace Session 对象?
【发布时间】:2013-12-05 09:22:26
【问题描述】:

我想序列化和存储 Ace Session 对象,这样我就可以打开一个“文件”并恢复所有内容、值、选择、光标位置、模式等。

我试过JSON.stringify(session),它会抛出一个循环错误。

有什么想法吗?

【问题讨论】:

标签: javascript ace-editor


【解决方案1】:

最简单的版本是

var session = editor.session
state = {}
state.value = session.getValue();
state.selection = session.selection.toJSON()
state.options = session.getOptions()
state.mode = session.getMode().$id
state.folds = session.getAllFolds().map(function(fold) {
    return {
        start       : fold.start,
        end         : fold.end,
        placeholder : fold.placeholder
    };
});
state.scrollTop = session.getScrollTop()
state.scrollLeft = session.getScrollLeft()

JSON.stringify(state)

恢复

session.setValue(state.value)
session.selection.fromJSON(state.selection)
session.setOptions(state.options)
session.setMode(state.mode)
try {
    state.folds.forEach(function(fold){
        session.addFold(fold.placeholder, 
            Range.fromPoints(fold.start, fold.end));
    });
} catch(e) {}
session.setScrollTop(state.scrollTop)
session.setScrollTop(state.scrollLeft)

这不包括恢复 undomanager,这是可行的,但有点棘手。你可以尝试解决这个问题https://github.com/ajaxorg/ace/issues/1452

【讨论】:

  • 感谢您的回复,将尽快尝试并报告:)
  • 在 devtools 中转到 js-play.com,运行 root.ace._session.selection.toJSON() - 没有 toJSON 函数,JSON.stringfy 是循环的。哪个版本有toJSON
  • 太棒了,试试看
  • 谢谢你——文档真的让我们失望了。在找到这个答案之前,我几乎想切换到 codemirror。
【解决方案2】:

我的解决方案结合了 3 个来源:

将会话序列化代码移至单独的模块:

editor-session.js:

var ace = require('brace');
var Range = ace.acequire('ace/range').Range;

var filterHistory = function(deltas) {
    return deltas.filter(function (d) {
        return d.group != "fold";
    });
};

/** @param {AceAjax.Editor} editor */
function sessionToJson(editor)
{
    return {
        content: editor.getSession().getValue(),
        selection: editor.getSelection().toJSON(),
        options: editor.getOptions(),
        mode: editor.session.getMode().$id,
        scrollTop: editor.session.getScrollTop(),
        scrollLeft: editor.session.getScrollLeft(),
        history: {
            undo: editor.session.getUndoManager().$undoStack.map(filterHistory),
            redo: editor.session.getUndoManager().$undoStack.map(filterHistory)
        },
        folds: editor.session.getAllFolds().map(function(fold) {
            return {
                start       : fold.start,
                end         : fold.end,
                placeholder : fold.placeholder
            };
        })
    }
}

/** @param {AceAjax.Editor} editor */
function jsonToSession(editor, state)
{
    editor.session.setValue(state.content);
    editor.selection.fromJSON(state.selection);
    editor.session.setOptions(state.options);
    editor.session.setMode(state.mode);
    editor.session.setScrollTop(state.scrollTop);
    editor.session.setScrollLeft(state.scrollLeft);
    editor.session.$undoManager.$undoStack = state.history.undo;
    editor.session.$undoManager.$redoStack = state.history.redo;
    try {
        state.folds.forEach(function(fold) {
            editor.session.addFold(fold.placeholder, Range.fromPoints(fold.start, fold.end));
        });
    } catch(e) {console.log('Fold exception: ' + e)}
}

module.exports.sessionToJson = sessionToJson;
module.exports.jsonToSession = jsonToSession;

浏览器端JS:由browserify处理

var ace = require('brace');
var state = require('./editor-session');
var editor = ace.edit('web-editor');

...

function saveEditorSession() {
    localStorage.setItem('editorSession', JSON.stringify(state.sessionToJson(editor)));
}

editor.getSession().on("change", function () {
    textarea.value = editor.getSession().getValue();
    // Save editor session to localStorage
    saveEditorSession();
    // Send editor content to backend
    ajax.saveContent(textarea.value, function (response) { });
});

editor.getSession().selection.on('changeSelection', saveEditorSession);
editor.getSession().selection.on('changeCursor', saveEditorSession);
editor.getSession().on('changeFold', saveEditorSession);
editor.getSession().on('changeScrollLeft', saveEditorSession);
editor.getSession().on('changeScrollTop', saveEditorSession);

【讨论】:

  • 建议:使用 editorOptions : editor.getOptions(), options : editor.getSession().getOptions()editor.session.setOptions(state.options); editor.setOptions(state.editorOptions); - 自从您发布此内容后,api 可能已更改,我的原始代码出现错误。
猜你喜欢
  • 1970-01-01
  • 2011-01-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-06
  • 1970-01-01
  • 2010-10-27
相关资源
最近更新 更多