是否有一个Jquery函数可以从解析的JSON字符串中获取#ref id值并指向引用的对象?

我整个下午一直在寻找这个问题的答案,我似乎无法找到完成我需要的最佳方法。

我的JSON字符串(从Web服务返回)中有循环引用(#ref),它指向字符串中的$ id。 现在我知道如果使用jquery parseJSON它会创建javascript对象,我可以访问la myObject.MyPropertyName属性。 但是,当我到达#ref时,我不确定如何获取ID指向的对象(我假设已经因为反序列化而创建了…

我应该迭代对象及其所有子对象,直到找到它,或者是否有更简单的方法?

$.ajax({ type: "POST", url: "/Task.asmx/GetTask", data: "{'id':'" + '27' + "'}", contentType: "application/json; charset=utf-8", dataType: "json", success: function (msg) { _Data = $.parseJSON(msg.d ? msg.d : msg); _this.Company = _Data[0].t_Program.t_Company; _this.Program = _Data[0].t_Program; _this.Task = _Data[0]; }, complete: function () { } }); 

有问题的区域是_Data [0] .t_Program,因为它不返回对象而是返回

 _Data[0].t_Program {...} $ref: "12" 

我不知道用$ id“12”获取对象的最佳方法。 根据下面的post,似乎我应该遍历现有的对象,但我希望有一个jquery函数,这样做…

非常感谢!

不,jQuery本身不能解析从JSON转换的对象中的循环引用。

我知道的唯一库是Dojo的dojox.json.ref模块 。

但是,您的服务器应用程序以某种方式序列化该JSON。 不要告诉我它使用的解决方案不提供反序列化算法!

正如我的朋友艾伦,Xerox Courier(RPC over the net)库的作者曾经对我说的那样,“电线上没有指针。”

换句话说,数据结构的JSON表示不可能是循环的。 (但是循环结构可以展平为非圆形JSON结构。)正如JSON网站所说:

JSON基于两种结构:

名称/值对的集合。 在各种语言中,这被实现为对象,记录,结构,字典,散列表,键控列表或关联数组。

有序的值列表。 在大多数语言中,这被实现为数组,向量,列表或序列。

没有指针!

因此,在jQuery parseJSON操作完成后,整个JSON将变为Javascript对象和/或数组。

如果原始结构的ref_id值被用作JSON / Javascript对象中的属性名称,那么它们都将在那里。

真正的问题是您需要了解服务器如何将其数据结构序列化为JSON数据结构。 查看服务器端代码以确定它。

然后使用Javascript将JSON结构反序列化为最佳Javascript结构以满足您的需求。

Re:我应该迭代对象及其所有子对象,直到找到它,还是有更简单的方法?

更简单的方法是遍历Javascript结构一次,并构建一个额外的“索引”对象,其属性为#ref_id,值为原始结构/值。

示例:var jsonCyclicReferenceFixed = JsonRecursive.parse(jsonWithRefAndId);

 (function(){ function type(value){ var t = typeof(value); if( t == "object" && value instanceof Array) { return "array"; } if( t == "object" && value && "$id" in value && "$values" in value) { return "array"; } return t; } function TypeConverterFactory(){ var converters = {}; var defaultConverter = { fromJson: function(value){ return value; }, toJson: function(value){ return value; }, }; this.create = function(type){ var converter = converters[type]; if(!converter) return defaultConverter; return converter; }; this.register = function(type, converter){ converters[type] = converter; converter.valueConverter = this.valueConverter; }; } function ObjectConverter(){ this.fromJson = function(obj){ if( obj == null ) return null; if( "$ref" in obj ){ var reference = this.dictionary[obj.$ref]; return reference; } if("$id" in obj){ this.dictionary[obj.$id] = obj; delete obj.$id; } for(var prop in obj){ obj[prop] = this.valueConverter.convertFromJson(obj[prop]); } return obj; } this.toJson = function(obj){ var id = 0; if(~(id = this.dictionary.indexOf(obj))){ return { "$ref" : (id + 1).toString() }; } var convertedObj = { "$id" : this.dictionary.push(obj).toString() }; for(var prop in obj){ convertedObj[prop] = this.valueConverter.convertToJson(obj[prop]); } return convertedObj; } } function ArrayConverter(){ var self = this; this.fromJson = function(arr){ if( arr == null ) return null; if("$id" in arr){ var values = arr.$values.map(function(item){ return self.valueConverter.convertFromJson(item); }); this.dictionary[arr.$id] = values; delete arr.$id; return values; } return arr; } this.toJson = function(arr){ var id = 0; if(~(id = this.dictionary.indexOf(arr))){ return { "$ref" : (id + 1).toString() }; } var convertedObj = { "$id" : this.dictionary.push(arr).toString() }; convertedObj.$values = arr.map(function(arrItem){ return self.valueConverter.convertToJson(arrItem); }); return convertedObj; } } function ValueConverter(){ this.typeConverterFactory = new TypeConverterFactory(); this.typeConverterFactory.valueConverter = this; this.typeConverterFactory.register("array", new ArrayConverter); this.typeConverterFactory.register("object", new ObjectConverter); this.dictionary = {}; this.convertToJson = function(valor){ var converter = this.typeConverterFactory.create(type(valor)); converter.dictionary = this.dictionary; return converter.toJson(valor); } this.convertFromJson = function(valor){ var converter = this.typeConverterFactory.create(type(valor)); converter.dictionary = this.dictionary; return converter.fromJson(valor); } } function JsonRecursive(){ this.valueConverter = new ValueConverter(); } JsonRecursive.prototype.convert = function(obj){ this.valueConverter.dictionary = []; var converted = this.valueConverter.convertToJson(obj); return converted; } JsonRecursive.prototype.parse = function(string){ this.valueConverter.dictionary = {}; var referenced = JSON.parse(string); return this.valueConverter.convertFromJson(referenced); } JsonRecursive.prototype.stringify = function(obj){ var converted = this.convert(obj); var params = [].slice.call(arguments, 1); return JSON.stringify.apply(JSON, [converted].concat(params)); } if(window){ if( window.define ){ //to AMD (require.js) window.define(function(){ return new JsonRecursive(); }); }else{ //basic exposition window.jsonRecursive = new JsonRecursive(); } return; } if(global){ // export to node.js module.exports = new JsonRecursive(); } }()); 

样品:

 // a object recursive // var parent = {}; // var child = {}; // parent.child = child; // child.parent = parent; // //results in this recursive json var json = '{"$id":"0","name":"Parent","child":{"$id":"1","name":"Child","parent":{"$ref":"0"}}}' //Parsing a Recursive Json to Object with references var obj = jsonRecursive.parse(json); // to see results try console.log( obj ); alert(obj.name); alert(obj.child.name);