如果我从json.net获得序列化的JSON,如下所示:

User:{id:1,{Foo{id:1,prop:1}},
FooList{$ref: "1",Foo{id:2,prop:13}}

我想让 knockout 在FooList上输出foreach,但是我不确定如何进行操作,因为$ ref东西可能会抛出东西。

我在想解决方案将以某种方式通过不使用以下方式强制将所有Foos呈现在FooList中:
PreserveReferencesHandling = PreserveReferencesHandling.Objects

但这似乎很浪费。

最佳答案

您从服务器接收的json对象包含Circular References。在使用该对象之前,您必须首先从该对象中删除所有$ref属性,这意味着您必须放置该链接指向的对象来代替$ref : "1"

您的情况可能是指向ID为1的User对象

为此,您应该检查Douglas Crockfords Plugin on github。有一个cycle.js可以为您完成这项工作。

或者您可以使用以下代码(未经测试):

function resolveReferences(json) {
    if (typeof json === 'string')
        json = JSON.parse(json);

    var byid = {}, // all objects by id
        refs = []; // references to objects that could not be resolved
    json = (function recurse(obj, prop, parent) {
        if (typeof obj !== 'object' || !obj) // a primitive value
            return obj;
        if ("$ref" in obj) { // a reference
            var ref = obj.$ref;
            if (ref in byid)
                return byid[ref];
            // else we have to make it lazy:
            refs.push([parent, prop, ref]);
            return;
        } else if ("$id" in obj) {
            var id = obj.$id;
            delete obj.$id;
            if ("$values" in obj) // an array
                obj = obj.$values.map(recurse);
            else // a plain object
                for (var prop in obj)
                    obj[prop] = recurse(obj[prop], prop, obj)
            byid[id] = obj;
        }
        return obj;
    })(json); // run it!

    for (var i=0; i<refs.length; i++) { // resolve previously unknown references
        var ref = refs[i];
        ref[0][ref[1]] = byid[refs[2]];
        // Notice that this throws if you put in a reference at top-level
    }
    return json;
}

让我知道是否有帮助!

10-05 20:30
查看更多