尝试解析JSON时,在位置0的JSON中出现意外的标记u

时间:2017-04-11 17:26:07

标签: javascript json d3.js

我尝试用here中的d3绘制树。

当我尝试解析它时会出现错误:Uncaught SyntaxError:位于0的JSON中出现意外的标记u     在JSON.parse()     在测试:44

代码在这里:

function getTree() {
        $.ajax({
            url: "/Test/FPTree",
            dataType: 'json',
            success: function (data) {
                return data;
            }
        })
    }
    var treeData = [];

    treeData.push(JSON.parse(getTree()));

    var margin = { top: 20, right: 120, bottom: 20, left: 120 },
        width = 960 - margin.right - margin.left,
        height = 500 - margin.top - margin.bottom;

    var i = 0;

    var tree = d3.layout.tree()
        .size([height, width]);

    var diagonal = d3.svg.diagonal()
        .projection(function (d) { return [d.y, d.x]; });

    var svg = d3.select("body").append("svg")
        .attr("width", width + margin.right + margin.left)
        .attr("height", height + margin.top + margin.bottom)
        .append("g")
        .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

    root = treeData[0];

    update(root);

    function update(source) {

        var nodes = tree.nodes(root).reverse(),
            links = tree.links(nodes);

        nodes.forEach(function (d) { d.y = d.depth * 180; });

        var node = svg.selectAll("g.node")
            .data(nodes, function (d) { return d.id || (d.id = ++i); });

        var nodeEnter = node.enter().append("g")
            .attr("class", "node")
            .attr("transform", function (d) {
                return "translate(" + d.y + "," + d.x + ")";
            });

        nodeEnter.append("circle")
            .attr("r", 10)
            .style("fill", "#fff");

        nodeEnter.append("text")
            .attr("x", function (d) {
                return d.children || d._children ? -13 : 13;
            })
            .attr("dy", ".35em")
            .attr("text-anchor", function (d) {
                return d.children || d._children ? "end" : "start";
            })
            .text(function (d) { return d.name; })
            .style("fill-opacity", 1);

        var link = svg.selectAll("path.link")
            .data(links, function (d) { return d.target.id; });

        link.enter().insert("path", "g")
            .attr("class", "link")
            .attr("d", diagonal);
    }

这是我的服务器JSON(使用Postman得到它)的有效。:

{
  "name": null,
  "parent": null,
  "children": [
    {
      "name": "A",
      "parent": null,
      "children": [
        {
          "name": "B",
          "parent": "A",
          "children": [
            {
              "name": "C",
              "parent": "B",
              "children": []
            }
          ]
        }
      ]
    }
  ]
}

来自控制器行动的代码

 [HttpGet]
    public ContentResult FPTree()
    {
        FPTree Tree = new FPTree();
        Tree.Add(new List<string> { "A", "B", "C" });

        var settings = new JsonSerializerSettings
        {
            Converters = new List<JsonConverter> { new FPTreeConverter() },
            Formatting = Formatting.Indented
        };
        return Content(JsonConvert.SerializeObject(Tree.root, settings), "application/json");
    }

2 个答案:

答案 0 :(得分:0)

您正在调用该函数并在实际检索之前“使用”数据。

你应该使用你承诺的回调函数中的承诺里面返回的数据,而不是在AJAX之外,而不是在它之外。

换句话说:您调用getTree(),因此启动AJAX请求,并尝试在调用后立即解析它返回的数据。但是,AJAX请求需要一些时间(这取决于许多事情,但通常在一秒钟之内)来处理和返回数据,因为它是异步的。当调用成功回调时,你的另一个函数已经停止了,因为getTree()的返回数据是undefined(因此你得到的解析错误就是“u”)。

尝试这样的事情:

    var tree = d3.layout.tree().size([height, width]);

    function getTree() {
        $.ajax({
            url: "/Test/FPTree",
            dataType: 'json',
            success: function (data) {

                var treeData = [];
                treeData.push(JSON.parse(data));

                var margin = { top: 20, right: 120, bottom: 20, left: 120 },
                    width = 960 - margin.right - margin.left,
                    height = 500 - margin.top - margin.bottom;
                var i = 0;

                var diagonal = d3.svg.diagonal()
                    .projection(function (d) { return [d.y, d.x]; });
                var svg = d3.select("body").append("svg")
                    .attr("width", width + margin.right + margin.left)
                    .attr("height", height + margin.top + margin.bottom)
                    .append("g")
                    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
                root = treeData[0];
                update(root);
            }
        })
    }

    function update(source) {
        var nodes = tree.nodes(root).reverse(),
            links = tree.links(nodes);

        nodes.forEach(function (d) { d.y = d.depth * 180; });

        var node = svg.selectAll("g.node")
            .data(nodes, function (d) { return d.id || (d.id = ++i); });

        var nodeEnter = node.enter().append("g")
            .attr("class", "node")
            .attr("transform", function (d) {
                return "translate(" + d.y + "," + d.x + ")";
            });

        nodeEnter.append("circle")
            .attr("r", 10)
            .style("fill", "#fff");

        nodeEnter.append("text")
            .attr("x", function (d) {
                return d.children || d._children ? -13 : 13;
            })
            .attr("dy", ".35em")
            .attr("text-anchor", function (d) {
                return d.children || d._children ? "end" : "start";
            })
            .text(function (d) { return d.name; })
            .style("fill-opacity", 1);

        var link = svg.selectAll("path.link")
            .data(links, function (d) { return d.target.id; });

        link.enter().insert("path", "g")
            .attr("class", "link")
            .attr("d", diagonal);
    }

答案 1 :(得分:0)

看起来你的getTree()函数实际上并没有返回任何东西。它正在返回undefined,这就是您收到该错误消息的原因。问题在于你的ajax调用中的success函数,你返回数据,但是你只返回传递给success参数的匿名函数。 getTree()函数实际上会立即返回,因为ajax调用是异步的。相反,你应该使用回调函数。也就是说,将一个函数传递给getTree()函数,该函数在完成后将使用数据调用。这是一个例子。

function getTree(callback) {
    $.ajax({
        url: "/Test/FPTree",
        dataType: 'json',
        success: function (data) {
            callback(data);
        }
    })
}

getTree(function(data) {

    var treeData = [];

    treeData.push(JSON.parse(getTree()));

    var margin = { top: 20, right: 120, bottom: 20, left: 120 },
    width = 960 - margin.right - margin.left,
    height = 500 - margin.top - margin.bottom;

    var i = 0;

    var tree = d3.layout.tree()
    .size([height, width]);

    var diagonal = d3.svg.diagonal()
    .projection(function (d) { return [d.y, d.x]; });

    var svg = d3.select("body").append("svg")
    .attr("width", width + margin.right + margin.left)
    .attr("height", height + margin.top + margin.bottom)
    .append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

    root = treeData[0]

    update(root)
});