我有一个看似复杂的问题,我不知道如何解决。
我的单页应用程序使用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会发生什么。
答案 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