0

我整个下午都在寻找这个问题的答案,但我似乎找不到完成我需要做的事情的最佳方法。

我的 JSON 字符串(从 Web 服务返回)中有循环引用(#ref),指向字符串中的 $id。现在我知道如果使用 jquery parseJSON 它会创建 javascript 对象,我可以访问属性 a 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" 获取对象的最佳方法。根据下面的帖子,我似乎应该遍历现有对象,但我希望有一个 jquery 函数可以做到这一点......

非常感谢!

4

3 回答 3

1

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

我知道的唯一库是Dojo 的dojox.json.refmodule

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

于 2012-05-25T01:40:20.653 回答
0

正如我的朋友艾伦(Xerox Courier(网络上的 RPC)库的作者)曾经对我说的,“网络上没有指针”。

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

JSON 建立在两种结构之上:

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

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

没有指针!

jQuery parseJSON所以在操作完成后,整个 JSON 将被转换为 Javascript 对象和/或数组。

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

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

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

回复:我应该遍历对象及其所有子对象直到找到它,还是有更简单的方法?

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

于 2012-05-25T01:41:35.977 回答
0

示例: 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);
于 2012-09-27T13:06:12.180 回答