3

私の webapp には、元に戻す/やり直しの概念があります。どのように実装するのが最善かを検討しています。

私の現在のアプローチは、各配列がそのバージョンを復元するために呼び出すコールバックの束である配列の配列を持つことです。たとえば、古い値を復元するラベルは次のようになります。

var undoer = {
    at = 0,
    stack = [[]],
    push = function(do,undo) {
        if(undoer.at > 0) {
            undoer.splice(0,undoer.at,[]);
            undoer.at = 0;
        }
        undoer.stack[0].push([do,undo]);
    },
    commit = function() { 
        if(undoer.at == 0 && undoer.stack[0])
            stack.unshift([]);
    },
    rollback = function() {
        if(undoer.at == 0 && undoer.stack[0])
            while(var func: stack[0].pop())
                func[1]();
    },
    undo = function() {
        // move the at index back, call all the undos
    ...
    redo = function() {
        // move the at index forward, call al dos
    ...
};

function Label(text) {
    var _text = text,
        label = {
            get: function() { return _text; },
            set: function(text) {
                var old = text;
                _text = text;
                undoer.push(
                    function() { _text = text; }, // do
                    function() { _text = old; } // undo
                );
            },
            ...
    };
    return label;
}

(この疑似コードのタイプミスと脱落についてお詫びします)

これは、クロージャーの変更を元に戻したりやり直したりするために必要な状態の変更を保存しています。

何千もの編集を想像してみてください。arguments代わりに可変引数関数を使用し、のコピーを元に戻すスタックに入れる方が、メモリ効率が高くなりますか?

また、元に戻す/やり直すためのより良い方法はありますか?

4

1 に答える 1

1

はい。

しかし、それらは読みやすく、使用しやすく、維持しやすいです。「正しい」答えはなく、費用対効果の分析のみです。あまり深く再帰しないようにしてください。

于 2012-11-17T17:55:34.613 に答える