从javascript中任意复杂的JSON对象生成html
这里是Javascript/jQuery新手 我的Web服务器正在将目录树的内容作为JSON对象发送。根据包含其他子目录的子目录的数量,对象可以任意嵌套。看起来是这样的:从javascript中任意复杂的JSON对象生成html,javascript,jquery,json,Javascript,Jquery,Json,这里是Javascript/jQuery新手 我的Web服务器正在将目录树的内容作为JSON对象发送。根据包含其他子目录的子目录的数量,对象可以任意嵌套。看起来是这样的: { "contents": [ { "filename": "myfile", "mtime": 123456, "size": 2345, "content": nil },
{
"contents": [
{
"filename": "myfile",
"mtime": 123456,
"size": 2345,
"content": nil
},
{
"filename": "mydir",
"mtime": 2345678,
"size": 3456788,
"content": [
{...},
{...}
]
}
]
}
myfile是一个普通文件,因此“内容”为空。mydir是一个可能为空的目录,或包含其他文件或子目录
我想用javascript解析这个JSON,并生成内容的html ul表示。我的问题是:有没有一种简单/推荐的方法可以做到这一点 如果您使用jQuery通过ajax调用接收JSON文本,jQuery会将其反序列化为对象图。如果您以其他方式接收它并将其保存在字符串中,则可以使用进行反序列化 但是,您引用的JSON无效,特别是这一位:
"content": nil
JSON中没有nil
关键字。您需要修复服务器,要么完全关闭密钥,要么使用null
,或者其他方法。有效的JSON是在上定义的,您可以使用它进行方便的验证(和格式化)。一致使用内容
或内容
也可能有用;当前顶层使用内容
,而下级条目使用内容
一旦有了对象图,递归函数就相当简单了,循环遍历数组条目,对于可以包含嵌套内容的条目,再次调用自身来循环遍历。像这样模糊的东西():
jQuery(函数($){
显示(“加载JSON数据”);
$.ajax({
键入:“获取”,
url:“/path/to/the/data”,
数据类型:“JSON”,
成功:功能(数据){
显示(“获取数据,呈现数据”);
$(document.body).append(renderContents(data.contents));
},
错误:函数(){
显示(“发生错误”);
}
});
函数呈现内容(contents){
var指数,ul;
//为这些内容创建一个列表
ul=$(“”);
//填写
$.each(内容、功能(索引、条目){
李华;
//创建列表项
li=$(“- ”);
//设置文本
li.text(entry.filename);
//附加其内容的子列表(如果有)
if(entry.content){
li.append(renderContents(entry.content));
}
//将此项目添加到我们的列表中
ul.附加(li);
});
//还它
返回ul;
}
功能显示(msg){
$(“”).html(msg.appendTo(document.body);
}
});
使用jQuery。在jQueryajax
函数中,对数据类型使用json
,它将自动解析json并返回一个json对象。您可以使用jQuery遍历json数组中的每个函数,并使用其中的数据创建ui
$.ajax({url:'ur url',dataType:'json',success:function(result){
var dhtml="<ul>";
$.each(result.contents,function(key,value){
dhtml+="<li><span>"+value.filename+"</span><span>"+value.mtime+"</span></li>";
})
dhtml+="</ul>";
$(body).append(dhtml);//Will add the result to ur html body
}
})
$.ajax({url:'ururl',数据类型:'json',成功:函数(结果){
var dhtml=“”;
$.each(结果、内容、函数(键、值){
dhtml+=“- ”+value.filename+”+value.mtime+“
”;
})
dhtml+=“
”;
$(body.append(dhtml);//将结果添加到您的html正文中
}
})
循环遍历这种遍历结构的最简单方法通常是编写递归(“自调用”)函数:
// $parent is a jQuery object referring to an element
// you what to create the tree in.
// data is your (parsed) JSON object.
function displayFileTree($parent, data) {
if (data["contents"] && data["contents"].length) {
var contents = data["contents"];
// create a list element
$list = $("<ul/>");
// loop over the "contents"
for (var i = 0, len = contents.length; i < len; i++) {
// create list item, set its text and append it to the list
$item = $("<li/>").text(contents[i].filename).appendTo($list);
// call this function to create a sublist of the subitems
displayFileTree($item, contents[i]);
}
// add list to parent
$parent.append($list);
}
}
/$parent是引用元素的jQuery对象
//您可以选择要在其中创建树的内容。
//数据是您的(已解析的)JSON对象。
函数displayFileTree($parent,data){
if(数据[“内容”]&数据[“内容”]长度){
变量内容=数据[“内容”];
//创建一个列表元素
$list=$(“
”);
//在“内容”上循环
for(变量i=0,len=contents.length;i ”).text(内容[i].filename).appendTo($list);
//调用此函数以创建子项的子列表
displayFileTree($item,contents[i]);
}
//将列表添加到父级
$parent.append($list);
}
}
(此函数假设JSON是正确的,正如T.J.Crowder的回答所建议的,尤其是它在任何地方都使用“contents”作为键,而不是“content”。)
(编辑:在Crowder用类似的解决方案扩展他的答案之前,我就开始写这篇文章。)你试过什么了吗?请注意,这是无效的(“content”:nil
——JSON中没有nil
),谢谢大家的回答。将顶级“内容”改为“内容”。正如我在下面解释的,nil实际上是空的。您需要对文件名进行HTML转义,否则,如果它(比如)有一个符号(&
),在您将其解释为HTML时可能会造成麻烦。@Akhil
:您可以,但它违反了关注点分离。服务器正在生成JSON输出。它可以用于各种各样的事情;以HTML显示只是一种可能性。但在演示json中,没有此类数据可以转义na?@Akhil
:您无法预测文件名将是什么,不正确地从服务器转义文本只是一种糟糕的做法。(顺便说一句,“na”不是一个英文单词。)@T.J.Crowder如果它是文件夹中的文件列表,那么就不可能有这样的特殊字符。谢谢提醒。nil部分实际上是一个工件,因为我在编写json时查看(clojure)对象,该对象在服务器端被转换为json字符串。在实际的json中,nils被转换为null。我也按照你的建议修改了内容->内容。
// $parent is a jQuery object referring to an element
// you what to create the tree in.
// data is your (parsed) JSON object.
function displayFileTree($parent, data) {
if (data["contents"] && data["contents"].length) {
var contents = data["contents"];
// create a list element
$list = $("<ul/>");
// loop over the "contents"
for (var i = 0, len = contents.length; i < len; i++) {
// create list item, set its text and append it to the list
$item = $("<li/>").text(contents[i].filename).appendTo($list);
// call this function to create a sublist of the subitems
displayFileTree($item, contents[i]);
}
// add list to parent
$parent.append($list);
}
}