Is there a Jquery function that can take a #ref id value from a parsed JSON string and point me to the referenced object?

前端 未结 3 880
面向向阳花
面向向阳花 2020-12-11 14:33

I have been looking for an answer to this all afternoon and i cant seem to find the best way to accomplish what i need to.

My JSON string (returned from a web servic

相关标签:
3条回答
  • 2020-12-11 14:40

    No, jQuery is not natively capable of resolving circular references in objects converted from JSON.

    The only library for that which I know is Dojo's dojox.json.ref module.

    But, your server application serializes that JSON somehow. Don't tell me that the solution it uses does not offer a deserialisation algorithm!

    0 讨论(0)
  • 2020-12-11 14:53

    As my friend Alan, the author of the Xerox Courier (RPC over the net) library, used to say to me, "there are no pointers on the wire."

    In other words, it is impossible for a JSON representation of a data structure to be circular. (But a circular structure can be flattened into a non-circular JSON structure.) As the JSON site says:

    JSON is built on two structures:

    A collection of name/value pairs. In various languages, this is realized as an object, record, struct, dictionary, hash table, keyed list, or associative array.

    An ordered list of values. In most languages, this is realized as an array, vector, list, or sequence.

    No pointers!

    So the entire JSON will have been turned into Javascript Objects and/or Arrays after the jQuery parseJSON operation completes.

    If the original stucture's ref_id values were used as the property names in the JSON / Javascript object, then they'll all be there.

    The real issue is that you need to understand how your server serialized its data structure into the JSON data structure. Look in your server-side code to determine that.

    Then use Javascript to de-serialize the JSON structure back into the best Javascript structure to fit your needs.

    Re: Should i be iterating though the object and all its child objects until i find it, or is there an easier way?

    The easier way would be to go through the Javascript structure once, and build up an additional "indexing" object whose properties are the #ref_id and the values are the original structure/value.

    0 讨论(0)
  • 2020-12-11 14:55

    Sample: 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();   
    }
    
    
    }());
    

    Sample:

    // 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);
    
    0 讨论(0)
提交回复
热议问题