11

Knockout で Observable オブジェクトを複製して、ある種のトランザクション メカニズムを作成する最良の方法は何ですか?

たとえば、このモデルの編集:

var Action = function (name, ownerType, condition, expression, args) {
    var self = this;
    this.name = ko.observable(name);
    this.ownerType = ko.observable(ownerType);
    this.condition = ko.observable(condition);
    this.expression = ko.observable(expression);
    this.args = ko.observable(args);
};

ユーザーが編集する前に、そのオブジェクトの状態を保存したい。ユーザーが編集をキャンセルすると、オブジェクトの状態がロールバックされます。

最も簡単な方法は、次のような別のプロジェクトを作成することです。

self.tempAction = new Action(action.name(), action.ownerType(), action.condition(), action.expression(), action.args());

しかし、それがエレガントなソリューションであるかどうかはわかりません..

それで、何かアイデアはありますか?

4

1 に答える 1

15

私は通常、次のようなことをします。

まず、jQuery の$.extend関数を模倣する関数があります。targetオブジェクトのすべてのobservable(または観察できない) プロパティ値をオブジェクトに取り込みsourceます。

// extends observable objects intelligently
ko.utils.extendObservable = function ( target, source ) {
    var prop, srcVal, isObservable = false;

    for ( prop in source ) {

        if ( !source.hasOwnProperty( prop ) ) {
            continue;
        }

        if ( ko.isWriteableObservable( source[prop] ) ) {
            isObservable = true;
            srcVal = source[prop]();
        } else if ( typeof ( source[prop] ) !== 'function' ) {
            srcVal = source[prop];
        }

        if ( ko.isWriteableObservable( target[prop] ) ) {
            target[prop]( srcVal );
        } else if ( target[prop] === null || target[prop] === undefined ) {

            target[prop] = isObservable ? ko.observable( srcVal ) : srcVal;

        } else if ( typeof ( target[prop] ) !== 'function' ) {
            target[prop] = srcVal;
        }

        isObservable = false;
    }
    return target;
};

次に、copyコピーするオブジェクトを本質的に変換しJSONJSONコピーを取得して新しいJavaScriptオブジェクトを構築する関数があります。これにより、すべてのメモリ ポインターがコピーされず、元のオブジェクトと一致する新しいオブジェクトが作成されます。ここでの 1 つの重要な点は、新しいオブジェクトの空のインスタンスを渡す必要があることです (そうしないと、どのプロパティを入力するかわかりません)。

// then finally the clone function
ko.utils.clone = function(obj, emptyObj){
    var json = ko.toJSON(obj);
    var js = JSON.parse(json);

    return ko.utils.extendObservable(emptyObj, js);
};

その後、次のように使用できます。

var tempAction = ko.utils.clone(action, new Action());
于 2012-05-10T15:09:31.260 に答える