2

解決方法がわからない、複雑に思える問題があります。

私の単一ページ アプリケーションはノックアウト JS を使用しており、ビューで入力値の 1 つが変更されるたびにビュー モデルをキャッシュしたいと考えています。

問題があるのは、ビュー モデルの複雑さです。ローカル ストレージを使用するには、オブジェクトを文字列化する必要がありますが、再帰的な値があります。これを処理してオブジェクトを文字列化するロジックがあります。しかし、JSON 文字列を解析してオブジェクトに戻そうとすると、関数が失われます。

function cacheForm(agency) {
        //var serialized = stringifyOnce(agency);
        //var serialized = amplify.store("Agency", agency);#
        //var obj = new Object();
        //obj.test = "test";

        value = agency;

        var cache = [];
        parsed = JSON.stringify(value, function (key, value) {
            if (typeof value === 'object' && value !== null) {
                if (cache.indexOf(value) !== -1) {
                    // Circular reference found, discard key
                    return;
                }
                    // Store value in our collection
                    cache.push(value);
            }

            return value;
        });

        //var jsonString = JSON.stringify(cache);


        //cache = null; // Enable garbage collection

        var parsedRecursive = "{" + '"data"' + ":" + parsed + "," + '"expires"' + ":" + null + "}"; // Build the string based on how amplify likes it

        var obj = eval('(' + parsed + ')')

        var obj = jQuery.parseJSON(parsedRecursive);
        //// Put the object into storage
        //localStorage.setItem('Agency', parsedRecursive);

        myData = JSON.parse(parsedRecursive, function (key, value) {
            var type;
            if (value && typeof value === 'object') {
                type = value.type;
                if (typeof type === 'string' && typeof window[type] === 'function') {
                    return new (window[type])(value);
                }
            }
            return value;
        });

        //// Retrieve the object from storage
        //    var retrievedObject = localStorage.getItem('Agency');

        //    var obj = jQuery.parseJSON(parsedRecursive);

        //var agency2 = mapping.fromJS(obj);
        //agency;
        //amplify.store("Agency", agency);
        //amplify.store("Obj", obj);
        //var store = amplify.store(); // Look at all items by not providing a key
    }
});

eval を使用してみましたが、データのないオブジェクトが返されました。理解を助けるために、私のビュー モデルがどのように見えるかを説明します。これは、cachForm のエージェンシー パラメーターです。

また、増幅を使用してみましたが、ビューモデルの構造のために同じ問題が発生しました。

コード内のビューモデルで何が起こるかを示すスクリーンショットもいくつか添付しました。

JSON 形式を使用して文字列化する前の代理店ビュー モデル

私のJSON文字列

解析されてオブジェクトに割り当てられた JSON 文字列

4

2 に答える 2

2

viewModel 全体をキャッシュすることはお勧めできません。viewModel には、オブザーバブル、計算済み、関数、またはイベント ハンドラーが含まれています。ビューモデルのデータをキャッシュし、生データのみをキャッシュすることをお勧めします。

シリアル化について:

したがって、ビュー データをシリアル化するだけです ( ko.mapping.toJSONを使用します)。

  var json = ko.mapping.toJSON(viewModel);

適切なビュー モデルを再構築するには、初期化関数を使用することをお勧めします。これは、ビュー モデル コンストラクターであり、イベント ハンドラー、関数、および計算を追加する関数です。

  var initializer  = your_constructor;

ページパスなどのキャッシュキーも決定する必要があります。

  var cacheItem = {data : json, constructor : initializer};
  cache[key] = cacheItem;

デシリアライズ時:

キャッシュ アイテムを取得します。

var cacheItem = cache[key];
var viewModel = JSON.parse(cacheItem.data);

これで、viewModel に生データが含まれるようになりました。

viewModel = ko.mapping.fromJS(viewModel);

プロパティはオブザーバブルに変換されました。

コンストラクターがある場合は、それを呼び出します。

if(cacheItem.constructor)
     cacheItem.constructor.call(viewModel);

次に、ビューモデルは保存したとおりです。

お役に立てば幸いです。

于 2013-08-17T09:35:53.860 に答える