2

Newtonsoft JSON.Net を使用して、PreserveReferencesHandlingを有効にしてオブジェクトを逆シリアル化しています。jQuery は、JSON.Net が使用する $ref および $id 構文に基づく参照の再リンクをサポートしていません (jQuery がこの機能を何らかの形でサポートしているかどうかはわかりません)。

Douglas Crockford のcycle.jsを使用してみましたが、それは私のオブジェクトでは機能しないようです。返されたオブジェクトは、渡されたオブジェクトと同じです。

私は JSON.Net にあまり詳しくありませんが、.NET コンポーネントが出力する JSON をシリアル化 (または解析) する JavaScript ライブラリが見つからないようです。

オブジェクト参照を元に戻すにはどうすればよいですか?

4

3 に答える 3

4

私もこの問題の解決策を探していましたが、最終的に Douglas Crockford のJSON.retrocycle関数をハッキングしました。彼の関数は $ref= some numberでは機能しませんが、xpath のようなものを探します。

これは私の簡単で汚いバージョンです - これをそのまま使用しないでください - 私はクリーンアップを行っていません。おそらくプラグインである必要がありますが、それは仕事をし、始めるのに十分です:

function retrocycle(o) {
var self = this;
self.identifiers = [];
self.refs = [];

self.rez = function (value) {

    // The rez function walks recursively through the object looking for $ref
    // properties. When it finds one that has a value that is a path, then it
    // replaces the $ref object with a reference to the value that is found by
    // the path.

    var i, item, name, path;

    if (value && typeof value === 'object') {
        if (Object.prototype.toString.apply(value) === '[object Array]') {
            for (i = 0; i < value.length; i += 1) {
                item = value[i];
                if (item && typeof item === 'object') {
                    path = item.$ref;
                    if (typeof path === 'string' && path != null) {
                        //self.refs[parseInt(path)] = {};

                        value[i] = self.identifiers[parseInt(path)]
                    } else {
                        self.identifiers[parseInt(item.$id)] = item;
                        self.rez(item);
                    }
                }
            }
        } else {
            for (name in value) {
                if (typeof value[name] === 'object') {
                    item = value[name];
                    if (item) {
                        path = item.$ref;
                        if (typeof path === 'string' && path != null) {
                            //self.refs[parseInt(path)] = {};

                            value[name] = self.identifiers[parseInt(path)]
                        } else {
                            self.identifiers[parseInt(item.$id)] = item;
                            self.rez(item);
                        }
                    }
                }
            }
        }
    }

};
self.rez(o);
self.identifiers = [];
}

次のように使用します。

    $.post("url/function", { ID: params.ID }, function (data) {

        retrocycle(data)

        // data references should be fixed up now

    }, "json");
于 2012-10-15T14:29:32.483 に答える
0

これは私の拡張版 @Dimitri です。@Dimitri コードは、参照を再構築できないことがあります。誰かがコードを改善したら、教えてください。

よろしく、マルコ・アルベス。

if (typeof JSON.retrocycle !== 'function') {
    JSON.retrocycle = function retrocycle(o) {
        //debugger;

        var self = this;
        self.identifiers = [];
        self.refs = [];

        self.buildIdentifiers = function (value) {
            //debugger;

            if (!value || typeof value !== 'object') {
                return;
            }

            var item;

            if (Object.prototype.toString.apply(value) === '[object Array]') {
                for (var i = 0; i < value.length; i += 1) {
                    item = value[i];

                    if (!item || !item.$id || isNaN(item.$id)) {
                        if (item) {
                            self.buildIdentifiers(item);
                        }

                        continue;
                    }

                    self.identifiers[parseInt(item.$id)] = item;
                    self.buildIdentifiers(item);
                }

                return;
            }

            for (var name in value) {
                if (typeof value[name] !== 'object') {
                    continue;
                }

                item = value[name];

                if (!item || !item.$id || isNaN(item.$id)) {
                    if (item) {
                        self.buildIdentifiers(item);
                    }

                    continue;
                }

                self.identifiers[parseInt(item.$id)] = item;
                self.buildIdentifiers(item);
            }
        };

        self.rez = function (value) {

            // The rez function walks recursively through the object looking for $ref
            // properties. When it finds one that has a value that is a path, then it
            // replaces the $ref object with a reference to the value that is found by
            // the path.

            var i, item, name, path;

            if (value && typeof value === 'object') {
                if (Object.prototype.toString.apply(value) === '[object Array]') {
                    for (i = 0; i < value.length; i += 1) {
                        item = value[i];
                        if (item && typeof item === 'object') {

                            if (item.$ref)
                                path = item.$ref;

                            if (typeof path === 'string' && path != null) {
                                //self.refs[parseInt(path)] = {};

                                value[i] = self.identifiers[parseInt(path)];
                                continue;
                            }

                            //self.identifiers[parseInt(item.$id)] = item;
                            self.rez(item);
                        }
                    }
                } else {
                    for (name in value) {
                        if (typeof value[name] === 'object') {
                            item = value[name];
                            if (item) {
                                path = item.$ref;
                                if (typeof path === 'string' && path != null) {
                                    //self.refs[parseInt(path)] = {};

                                    value[name] = self.identifiers[parseInt(path)];
                                    continue;
                                }

                                //self.identifiers[parseInt(item.$id)] = item;
                                self.rez(item);
                            }
                        }
                    }
                }
            }

        };

        self.buildIdentifiers(o);
        self.rez(o);
        self.identifiers = []; // Clears the array
    };
}
于 2014-05-22T00:59:34.343 に答える
0

js パーサーにダブル ルックアップを書き込む必要があります。技術的に参照処理を維持することは、循環参照を回避することです。つまり、通常は解析中にスタック オーバーフローが発生します。

JSON には、これを処理するためのネイティブ構文がありません。Newtonsoft バージョンはカスタム実装であるため、JSON の解析はカスタム実装になります。

そのような参照を本当に保持する必要がある場合は、XML の方が優れたソリューションである可能性があります。json->xml ライブラリがいくつかあります。

役立つ可能性のある解析の解決策の 1 つ、または少なくともガイドを次に示し ます。

于 2012-10-12T19:07:40.957 に答える