繁体   English   中英

来自JSON的多层嵌套菜单

[英]Multi level nested menu from json

如何基于“ id”和“ pid”从JSON创建嵌套菜单(带有“ sub-sub-sub ...- n”)项?

代码详细信息:

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 + '';

但这仅执行一级父项。

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

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

由于您的输出未格式化,因此我首先创建一个父子级层次结构,然后将其用于打印输出。 我不是直接将值存储在字符串中,而是使用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); 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM