我有一个看起来很复杂的问题,我不知道如何解决。
我的单页应用程序使用knockoutJS,每次我的 View 上的输入值之一发生变化时,我想缓存我的 View 模型。
问题出在我的 View 模型的复杂性上。要使用本地存储,我需要对我的对象进行字符串化,但它具有递归值。我有一些逻辑来处理这个问题并字符串化我的对象。但是当我尝试将 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,但这返回了一个没有我的数据的对象。为了帮助您理解这是我的 View 模型的样子,它是 cachForm 的代理参数。
我也尝试使用 amplify,但由于我的 View 模型结构,我遇到了同样的问题。
我还附上了一些屏幕截图,以显示代码中我的 View 模型发生的情况。
最佳答案
缓存整个 viewModel 并不是一个好主意。 viewModel 包含可观察量、计算量和函数或事件处理程序。 您最好缓存 View 模型数据,仅缓存原始数据。
关于序列化:
所以只需序列化 View 数据(使用 ko.mapping.toJSON ):
var json = ko.mapping.toJSON(viewModel);
为了重建正确的 View 模型,最好有一个初始化函数。 这是您的 View 模型构造函数,即添加事件处理程序、函数和计算的函数。
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);
那么您的 View 模型就是您存储时的样子。
希望对您有所帮助。
关于json - ParseJSON 与 javascript 对象的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18249481/