0

私は午後中ずっとこれに対する答えを探していましたが、必要なことを達成するための最良の方法を見つけることができないようです.

私の JSON 文字列 (Web サービスから返された) には、文字列内の $id を指す循環参照 (#ref) が含まれています。jquery parseJSON を使用すると、javascript オブジェクトが作成され、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 over the net) ライブラリの作成者である友人の Alan がよく私に言ったように、「ネットワーク上にポインターはありません」。

つまり、データ構造のJSON 表現を循環させることは不可能です。(ただし、循環構造は、非循環 JSON 構造にフラット化できます。) JSON サイトが言うように:

JSON は、次の 2 つの構造で構築されています。

名前と値のペアのコレクション。さまざまな言語で、これはオブジェクト、レコード、構造体、辞書、ハッシュ テーブル、キー付きリスト、または連想配列として実現されます。

値の順序付きリスト。ほとんどの言語では、これは配列、ベクトル、リスト、またはシーケンスとして実現されます。

ポインタはありません!

jQuery parseJSONそのため、操作が完了すると、JSON 全体が Javascript オブジェクトや配列に変換されます。

元の構造の ref_id 値が JSON / Javascript オブジェクトのプロパティ名として使用された場合、それらはすべてそこにあります。

本当の問題は、サーバーがそのデータ構造をどのように JSON データ構造にシリアライズしたかを理解する必要があるということです。サーバー側のコードを調べて、それを判断してください。

次に、Javascript を使用して JSON 構造をデシリアライズし、ニーズに合わせて最適な Javascript 構造に戻します。

Re: オブジェクトとそのすべての子オブジェクトを見つけるまで繰り返し処理する必要がありますか、それとももっと簡単な方法がありますか?

簡単な方法は、Javascript 構造を 1 回調べて、プロパティが #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 に答える