Javascript nested loop
I do not code much in Javascript, but I have the following snippet which IMHO looks horrendous and I have to do this nested iteration quite often in my code. Does anyone have a prettier/easier to read solution?
function addBrowse(data) {
var list = $('<ul></ul>')
for(i = 0; i < data.list.length; i++) {
var file = list.append('<li class="toLeft">' + data.list[i].name + '</li>')
for(j = 0; j < data.list[i].children.length; j++) {
var db = file.append('<li>' + data.list[i].children[j].name + '</li>')
for(k = 0; k < data.list[i].children[j].children.length; k++)
db.append('<li class="toRight">' + data.list[i].children[j].children[k].name + '</li>')
}
}
$('#browse').append(list).show()}开发者_StackOverflow中文版
Here is a sample data element
{"file":"","db":"","tbl":"","page":"browse","list":[
{
"name":"/home/alex/GoSource/test1.txt",
"children":[
{
"name":"go",
"children":[
{
"name":"validation1",
"children":[
]
}
]
}
]
},
{
"name":"/home/alex/GoSource/test2.txt",
"children":[
{
"name":"go",
"children":[
{
"name":"validation2",
"children":[
]
}
]
}
]
},
{
"name":"/home/alex/GoSource/test3.txt",
"children":[
{
"name":"go",
"children":[
{
"name":"validation3",
"children":[
]
}
]
}
]
}]}
Thanks a lot
It might be better to look into a JavaScript templet engine:
- https://github.com/janl/mustache.js/
- https://github.com/jquery/jquery-tmpl
You can use jQuery's each()
function to make this look nicer:
function addBrowse(data) {
var list = $('<ul></ul>')
$.each(data.list, function(_, item) {
var file = list.append('<li class="toLeft">' + item.name + '</li>');
$.each(item.children, function(_, child) {
var db = file.append('<li>' + child.name + '</li>');
$.each(child.children, function(_, grandchild) {
db.append('<li class="toRight">' + grandchild.name + '</li>');
});
});
});
$('#browse').append(list).show();
}
A problem here, though, is that you introduce XSS vulnerabilities. You can use jQuery's text function to avoid that, though. Or, as Detroitpro points out, use a templating engine. Also, beware of performance implications when using $.each
- it's slower than a for
loop, but that won't matter much unless you do it many times.
it would be tempting to put the two inner loops in their own functions. This would simplify the code by removing all those nested children references. Although the function calls would cost time, a lot of array referencing would be removed, so you'll probably end up square. more importantly it would be simpler code.
If you're using jQuery, it has a fiew methods that can help you out:
function addBrowse(data) {
var list = $(document.createElement('ul')),
li = $(document.createElement('li')),
get_li;
get_li = function(value, className) {
className = className === undefined ? '' : className;
return li.clone().text(value).addClass(className);
};
$.each(data.list, function (i, v) {
list.append(get_li(v.name, 'toLeft'));
$.each(v.children, function(i, v2) {
list.append(get_li(v2.name));
$.each(v2.children, function(i, v3) {
list.append(get_li(v3.name, 'toRight'));
});
});
});
$('#browse').append(list).show();
}
精彩评论