来自json的多级嵌套菜单

时间:2016-11-15 07:09:36

标签: javascript jquery json

如何基于" id"从我的JSON创建嵌套菜单(带有" sub-sub-sub ... -n")项目。和" pid"?

代码详情:

id - item ID
lvl - level of the item
pid - parent ID of the item
pos - position of the item
nm - name of the item

JSON:

[{"id":1,"lvl":0,"pid":0,"pos":0,"nm":"HomeTree"},
{"id":5,"lvl":1,"pid":1,"pos":0,"nm":"Books"},
{"id":2,"lvl":1,"pid":1,"pos":1,"nm":"Jobs"},
{"id":16,"lvl":1,"pid":1,"pos":2,"nm":"Music"},
{"id":17,"lvl":2,"pid":16,"pos":0,"nm":"Relax Sets"},
{"id":12,"lvl":1,"pid":1,"pos":3,"nm":"Cars"},
{"id":13,"lvl":2,"pid":12,"pos":0,"nm":"BMW"},
{"id":14,"lvl":1,"pid":1,"pos":4,"nm":"Web"},
{"id":15,"lvl":2,"pid":14,"pos":0,"nm":"PHP Analytics"},
{"id":18,"lvl":1,"pid":1,"pos":5,"nm":"Hardware"},
{"id":19,"lvl":2,"pid":18,"pos":0,"nm":"EVGA SR2 Upgrades"},
{"id":31,"lvl":2,"pid":18,"pos":1,"nm":"Keyboards"},
{"id":20,"lvl":1,"pid":1,"pos":6,"nm":"Movies"},
{"id":21,"lvl":1,"pid":1,"pos":7,"nm":"Games"},
{"id":22,"lvl":1,"pid":1,"pos":8,"nm":"Robots"},
{"id":25,"lvl":1,"pid":1,"pos":9,"nm":"Magazines"},
{"id":26,"lvl":2,"pid":25,"pos":0,"nm":"IT Security"},
{"id":27,"lvl":1,"pid":1,"pos":10,"nm":"Management"},
{"id":28,"lvl":2,"pid":27,"pos":0,"nm":"Holacracy"},
{"id":29,"lvl":3,"pid":28,"pos":0,"nm":"Testtt"}]

我需要什么:

HomeTree
    Books
    Jobs
    Music
    Relax Sets
    Cars
        BMW
    Web
        PHP Analytics
    Hardware
        EVGA SR2 Upgrades
    Keyboards
    Movies
    Games
    Robots
    Magazines
        IT Security
    Management
        Holacracy
            Testtt

我目前的代码:

$.ajax({
    url: './jstree_head.php?operation=full_tree',
    data: "",
    dataType: 'json',
    success: function(data)
    {
        var output="<br />";
        for (var i in data)
        {
                var rid = data[i].id;
                var rpid = data[i].pid;
                var rlvl = data[i].lvl;
                var rnm = data[i].nm;

                var nest = '&nbsp; &nbsp; &nbsp;';
                if(rpid > 1) {
                                 nm = nest+rnm+'<br>';
                             }
                else {nm = rnm+'<br>';}

            output+='' + nm + '';
        }
        $('#content').html(output);
    }
});

现在我无法解释深层子级别,这样做的正确方法是什么?

---更新---

我尝试的是:

var nest = '&nbsp; &nbsp; &nbsp;';
if(rpid > 1) {
    nm = nest+rnm+'<br>';
}
else {nm = rnm+'<br>';}

output+='' + nm + '';

但这只是父级项目的一个级别。

2 个答案:

答案 0 :(得分:0)

由于您的数据是平面数组,而不是嵌套的JSON对象,因此您无法使用递归函数。

相反,您可以遍历所有元素,在lvl属性更改时跟踪列表父项。随着lvl的增加,将前一个元素添加到父项列表中,并将此最新父项用于以下所有项目。当lvl减少时,从列表中删除最新的父级,并在列表中使用前面的父级,而不是所有后续项目。

答案 1 :(得分:0)

由于您的输出未格式化,我首先创建一个父子层次结构,然后用于打印输出。我没有直接将值存储在字符串中,而是使用JSON,因为在那里动态添加子项要容易得多。

var data = [{"id":1,"lvl":0,"pid":0,"pos":0,"nm":"HomeTree"},
    {"id":5,"lvl":1,"pid":1,"pos":0,"nm":"Books"},
    {"id":2,"lvl":1,"pid":1,"pos":1,"nm":"Jobs"},
    {"id":16,"lvl":1,"pid":1,"pos":2,"nm":"Music"},
    {"id":17,"lvl":2,"pid":16,"pos":0,"nm":"Relax Sets"},
    {"id":12,"lvl":1,"pid":1,"pos":3,"nm":"Cars"},
    {"id":13,"lvl":2,"pid":12,"pos":0,"nm":"BMW"},
    {"id":14,"lvl":1,"pid":1,"pos":4,"nm":"Web"},
    {"id":15,"lvl":2,"pid":14,"pos":0,"nm":"PHP Analytics"},
    {"id":18,"lvl":1,"pid":1,"pos":5,"nm":"Hardware"},
    {"id":19,"lvl":2,"pid":18,"pos":0,"nm":"EVGA SR2 Upgrades"},
    {"id":31,"lvl":2,"pid":18,"pos":1,"nm":"Keyboards"},
    {"id":20,"lvl":1,"pid":1,"pos":6,"nm":"Movies"},
    {"id":21,"lvl":1,"pid":1,"pos":7,"nm":"Games"},
    {"id":22,"lvl":1,"pid":1,"pos":8,"nm":"Robots"},
    {"id":25,"lvl":1,"pid":1,"pos":9,"nm":"Magazines"},
    {"id":26,"lvl":2,"pid":25,"pos":0,"nm":"IT Security"},
    {"id":27,"lvl":1,"pid":1,"pos":10,"nm":"Management"},
    {"id":28,"lvl":2,"pid":27,"pos":0,"nm":"Holacracy"},
    {"id":29,"lvl":3,"pid":28,"pos":0,"nm":"Testtt"}];

var output="<br />";

var res = [];
function createRelationship(){
    for (var i in data)
    {
        if(data[i].pid == 0 && data[i].id == 1){
            res.push({
            id: data[i].id,
            nm: data[i].nm
            });
        }
        else{
            var parent = findParent(data[i].pid, res);
            if(parent){
                if(!parent.items){
                    parent.items = [];
                }
                parent.items.push({
                    id: data[i].id,
                    nm: data[i].nm
                });
            }
        }
    }
}

function findParent(pid, _res){
    if(_res){
        if(_res.id == pid){
            return _res;
        }
        var len = _res.length ? _res.length : _res.items ? _res.items.length : 0;
        for(var i =0; i< len; i++){
            if(_res[i] && _res[i].id == pid){
                return _res[i];
            }
            else{
                var child = _res[i] ? _res[i] : _res;
                if(child){
                    for(var j=0;j<child.items.length;j++){
                        var res = findParent(pid, child.items[j]);
                        if(res){
                            return res;
                        }
                    }
                }
            }
        }
    }
    return null;
}



function printOutPut(obj, spaceCount){
    var space = '';
    for(var i = 0; i< spaceCount; i++){
        space+= '&nbsp;';
    }
    output += space + obj.nm;
    output += "<br />";
    if(obj.items){
        for(i = 0; i < obj.items.length; i++){
            printOutPut(obj.items[i], (spaceCount + 4));
        }
    }
}

createRelationship();

for(var z =0; z<res.length;z++){
    printOutPut(res[z], 1);
}

document.write(output);