将List转换为嵌套对象树

时间:2014-06-02 13:21:38

标签: javascript angularjs tree treeview

我正在使用angular并希望在html中显示这样的文件夹的嵌套树:

<div id="tree">
    <ul>
        <li ng-repeat='folder in folderList' ng-include="'/templates/tree-renderer.html'"  id="{{ folder.htmlId }}">
        </li>
    </ul>
</div>

在tree-renderer.html中我有:

<a href='/#/folders{{ folder.link.href }}'>
    <span>{{folder.name}} 
        <small>{{ folder.nbDocIn }}
        </small>
    </span>
</a>
<ul>
    <li ng-repeat="folder in folder.children" ng-include="'/templates/tree-renderer.html'">
    </li>
</ul>

由于每次修改某些内容时都需要执行Rest请求,因此我得到了结果,我希望以下代码能够快速完成。

我从Rest请求中收到一个像这样的json:

        {
            "key": "folder1"
        },
        {
            "key": "folder2"
        },
        {
            "key": "folder1/subFolder1"
        },
        {
            "key": "folder2/subFolder2"
        },
        {
            "key": "folder1/subFolder2"
        },
        {
            "key": "folder2/subFolder2/subSubFolder2"
        }

不是必须订购列表。 正如您在html中看到的,我现在需要将此列表转换为此列表:

        {
            "key": "folder1",
             "children": [{
                    "key": "folder1/subFolder1"
              }, {
                    "key": "folder1/subFolder2"
              }]
        },{
            "key": "folder2",
             "children": [{
                    "key": "folder2/subFolder1",
                    "children": [{
                         "key": "folder2/subFolder1/subSubFolder2"
                    }]
              }]
        }

现在我需要两个递归函数才能实现,一个用于创建子项数组,另一个用于将这些数组放入属性子项

我想做一个,你有一些如何制作的想法吗?

1 个答案:

答案 0 :(得分:1)

基本上,最好从服务器端创建结构化列表而不是客户端。

但在您的情况下,您需要为每个元素标识父亲(文件夹)并将它们放在正确的项目中。所以你不需要递归。

功能代码:(2个功能:结构化和渲染)

var list = [{
        key: 'folder1'
    },{
        key: 'folder2'
    },{
        key: "folder1/subFolder1"
    },{
        key: "folder2/subFolder2"
    },{
        key: "folder1/subFolder3"
    },{
        key: "folder2/subFolder2/subSubFolder2"
    }];
    $('body').ready(function(){
        ord_list = construct_ord_list(list);
        construct_html(ord_list);
    });
    var construct_ord_list = function(list){
        var finished = false;
        var running = true;
    // Construct a list with a father property for each items
        var res = [];
        for(i in list)
            res.push({  key: list[i].key,   father: ''});
    // Identifying fathers
        while (!finished){
            if (!running)
                finished = true;
            running = false;
            for(i in res)
                if(res[i].key.indexOf('/') > -1){
                    running = true;
    // father recepts the left side of key value from '/'
                    res[i].father = res[i].key.substring(0,res[i].key.indexOf('/'));
    // key recepts the right side of key value from '/'
                    res[i].key = res[i].key.substring(res[i].key.indexOf('/')+1,res[i].key.length);
                }
        }
        return res;
    }
    var construct_html = function(list){
        var text = '<ul>';
        for(i in list)
            if(list[i].father == '')
                text += '<li id="item_'+list[i].key+'">'+list[i].key+'<ul class="children"></ul></li>';
        $('body').append(text+'</ul>');
        for(i in list)
            if(list[i].father != '')
                $('#item_'+list[i].father).find('.children').first().append('<li id="item_'+list[i].key+'">'+list[i].key+'<ul class="children"></ul></li>');
    }

显然JQuery不是必需的,但允许更易读的代码......

如果你真的想要一个由javascript构建的树,那么这两个函数将帮助你:(只有一个递归)

    var construct_tree = function(list){
        var res = [];
        for(i in list)
            if(list[i].father == '')
                res.push({  key: list[i].key,   children:   []});
        for(i in list)
            if(list[i].father != '')
                insert_child(res,list[i]);
        return res;
    }
    var insert_child = function(list,elmt){
        for(i in list)
            if (list[i].key == elmt.father)
                list[i].children.push({ key: list[i].key,   children:   []});
            else if (list[i].children.length > 0)
                insert_child(list[i].children,elmt);
    }