有没有将反序列化Json.Net参考循环处理现有的JavaScript库?
{
"$id": "1",
"AppViewColumns": [
{
"$id": "2",
"AppView": {"$ref":"1"},
"ColumnID": 1,
}
]
}
这应该反序列化到对象与所述对象之间的阵列中的和所述外对象的引用环
有没有将反序列化Json.Net参考循环处理现有的JavaScript库?
{
"$id": "1",
"AppViewColumns": [
{
"$id": "2",
"AppView": {"$ref":"1"},
"ColumnID": 1,
}
]
}
这应该反序列化到对象与所述对象之间的阵列中的和所述外对象的引用环
这些问题的答案几乎给出为我工作,但MVC,JSON.Net的最新版本,并使用DNX“$ REF”和“$ ID”,他们可能会失灵。 所以我修改user2864740的答案。
我要指出,这个代码不处理数组引用,这也是可能的。
function RestoreJsonNetReferences(g) { var ids = {}; function getIds(s) { // we care naught about primitives if (s === null || typeof s !== "object") { return s; } var id = s['$id']; if (typeof id != "undefined") { delete s['$id']; // either return previously known object, or // remember this object linking for later if (ids[id]) { throw "Duplicate ID " + id + "found."; } ids[id] = s; } // then, recursively for each key/index, relink the sub-graph if (s.hasOwnProperty('length')) { // array or array-like; a different guard may be more appropriate for (var i = 0; i < s.length; i++) { getIds(s[i]); } } else { // other objects for (var p in s) { if (s.hasOwnProperty(p)) { getIds(s[p]); } } } } function relink(s) { // we care naught about primitives if (s === null || typeof s !== "object") { return s; } var id = s['$ref']; delete s['$ref']; // either return previously known object, or // remember this object linking for later if (typeof id != "undefined") { return ids[id]; } // then, recursively for each key/index, relink the sub-graph if (s.hasOwnProperty('length')) { // array or array-like; a different guard may be more appropriate for (var i = 0; i < s.length; i++) { s[i] = relink(s[i]); } } else { // other objects for (var p in s) { if (s.hasOwnProperty(p)) { s[p] = relink(s[p]); } } } return s; } getIds(g); return relink(g); }
好了,所以我创建了将使用的$ id和$ ref上的更强大的方法,因为这是json.net实际上是如何处理循环引用。 你也有后的ID已被注册,否则将无法找到一个已经引用的对象,让您的引用,所以我也有认为所请求的参考对象,与他们要设置的属性和ID一起他们请求。
这在很大程度上lodash /下划线基于
(function (factory) {
'use strict';
if (typeof define === 'function' && define.amd) {
define(['lodash'], factory);
} else {
factory(_);
}
})(function (_) {
var opts = {
refProp: '$ref',
idProp: '$id',
clone: true
};
_.mixin({
relink: function (obj, optsParam) {
var options = optsParam !== undefined ? optsParam : {};
_.defaults(options, _.relink.prototype.opts);
obj = options.clone ? _.clone(obj, true) : obj;
var ids = {};
var refs = [];
function rl(s) {
// we care naught about primitives
if (!_.isObject(s)) {
return s;
}
if (s[options.refProp]) {
return null;
}
if (s[options.idProp] === 0 || s[options.idProp]) {
ids[s[options.idProp]] = s;
}
delete s[options.idProp];
_(s).pairs().each(function (pair) {
if (pair[1]) {
s[pair[0]] = rl(pair[1]);
if (s[pair[0]] === null) {
if (pair[1][options.refProp] !== undefined) {
refs.push({ 'parent': s, 'prop': pair[0], 'ref': pair[1][options.refProp] });
}
}
}
});
return s;
}
var partialLink = rl(obj);
_(refs).each(function (recordedRef) {
recordedRef['parent'][recordedRef['prop']] = ids[recordedRef['ref']] || {};
});
return partialLink;
},
resolve: function (obj, optsParam) {
var options = optsParam !== undefined ? optsParam : {};
_.defaults(options, _.resolve.prototype.opts);
obj = options.clone ? _.clone(obj, true) : obj;
var objs = [{}];
function rs(s) {
// we care naught about primitives
if (!_.isObject(s)) {
return s;
}
var replacementObj = {};
if (objs.indexOf(s) != -1) {
replacementObj[options.refProp] = objs.indexOf(s);
return replacementObj;
}
objs.push(s);
s[options.idProp] = objs.indexOf(s);
_(s).pairs().each(function (pair) {
s[pair[0]] = rs(pair[1]);
});
return s;
}
return rs(obj);
}
});
_(_.resolve.prototype).assign({ opts: opts });
_(_.relink.prototype).assign({ opts: opts });
});
我创建了一个要点这里
我不知道存在这样的支持库,但一个可以使用标准JSON.parse
方法,然后手动走,结果恢复循环引用-它会仅仅是基于$ id属性一个简单的存储/查询。 (A类似的方法可用于反转的过程。)
下面是一个使用这样的方法的一些示例代码。 此代码假定JSON已经被解析到相关的JS对象图 - 它还会修改所提供的数据。 因人而异。
function restoreJsonNetCR(g) {
var ids = {};
function relink (s) {
// we care naught about primitives
if (s === null || typeof s !== "object") { return s; }
var id = s['$id'];
delete s['$id'];
// either return previously known object, or
// remember this object linking for later
if (ids[id]) {
return ids[id];
}
ids[id] = s;
// then, recursively for each key/index, relink the sub-graph
if (s.hasOwnProperty('length')) {
// array or array-like; a different guard may be more appropriate
for (var i = 0; i < s.length; i++) {
s[i] = relink(s[i]);
}
} else {
// other objects
for (var p in s) {
if (s.hasOwnProperty(p)) {
s[p] = relink(s[p]);
}
}
}
return s;
}
return relink(g);
}
和使用
var d = {
"$id": "1",
"AppViewColumns": [
{
"$id": "2",
"AppView": {"$id":"1"},
"ColumnID": 1,
}
]
};
d = restoreJsonNetCR(d);
// the following works well in Chrome, YMMV in other developer tools
console.log(d);
DrSammyD创建下划线插件变种加上来回的支持 。