Javascript 尝试解析JSON时,JSON中位于位置0的意外标记u
我试着用d3画一棵树 当我试图解析它时,在JSON中的位置0处获取error:Uncaught SyntaxError:Unexpected token u 在JSON.parse()处 测试时:44 代码如下:Javascript 尝试解析JSON时,JSON中位于位置0的意外标记u,javascript,json,d3.js,Javascript,Json,D3.js,我试着用d3画一棵树 当我试图解析它时,在JSON中的位置0处获取error:Uncaught SyntaxError:Unexpected token u 在JSON.parse()处 测试时:44 代码如下: function getTree() { $.ajax({ url: "/Test/FPTree", dataType: 'json', success: function (data) {
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(使用邮递员获取),它是有效的:
{
"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");
}
[HttpGet]
公共内容结果FPTree()
{
FPTree-Tree=新的FPTree();
添加(新列表{“A”、“B”、“C”});
var设置=新的JsonSerializerSettings
{
转换器=新列表{new FPTreeConverter()},
格式化=格式化。缩进
};
返回内容(JsonConvert.SerializeObject(Tree.root,settings),“application/json”);
}
您正在调用函数并在实际检索数据之前“使用”数据
您应该在AJAX成功时调用的回调函数中使用promise返回的数据,而不是在它之外
换句话说:调用getTree(),因此启动AJAX请求,并尝试解析调用后立即返回的数据。但是,AJAX请求需要一些时间(这取决于许多事情,但通常不到一秒钟)来处理和返回数据,因为它是异步的。调用成功回调时,另一个函数已经停止,因为getTree()返回的数据是未定义的(因此在解析错误中出现“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);
}
看起来在您的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)
});
您的JSON是“未定义”的,您在调用JSON之前没有等待结果返回。parse
getTree
正在调用一个ajax
函数,并且没有返回任何内容,因此您的JSON.parse
失败。您需要做的是将所有需要数据的逻辑封装到函数中,并在收到数据后从ajax
success
调用它