ParseJSON具有javascript对象的函数

时间:2013-08-15 09:04:02

标签: json knockout.js local-storage javascript recursive-datastructures

我有一个看似复杂的问题,我不知道如何解决。

我的单页应用程序使用knockoutJS,每当我的视图中的一个输入值发生变化时,我想缓存我的视图模型。

问题在于我的视图模型的复杂性。要使用本地存储,我需要对我的对象进行字符串化,但它具有递归值。我有一些逻辑来处理这个并将我的对象字符串化。但是当我尝试将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的代理参数。

此外,我尝试使用放大,但由于我的视图模型结构,我遇到了同样的问题。

我还附上了一些截图,以显示代码中我的viewmodel会发生什么。

My Agency view model before stringifying it using JSON format

My JSON string

My JSON string parsed and assigned to an object

2 个答案:

答案 0 :(得分:2)

缓存整个viewModel并不是一个好主意。 viewModel包含可观察对象,计算机和函数或事件处理程序。 您最好缓存视图模型数据,只缓存原始数据。

序列化:

所以只需序列化视图数据(使用ko.mapping.toJSON):

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

为了重建正确的视图模型,最好具有初始化功能。 这是你的视图模型构造函数e.i.添加事件处理程序,函数和计算的函数。

  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);

然后您的视图模型就像存储它一样。

我希望它有所帮助。

答案 1 :(得分:1)

这是我在另一篇文章中发布的答案。他们都是相关的。

JSON.parse returns children objects with null value, children values not being parsed