web-dev-qa-db-ja.com

bootstrap treeviewに動的にノードを追加する

現在、ブートストラップツリービューを作成するための巨大なJSONファイル(15,000行を超えると、サイズが大きくなる可能性があります)があります。すべてのノードを追加するとページの読み込みが非常に遅くなるため、選択したノードのJSONをフェッチし、それに応じてツリービューにデータを入力するサービスを作成する予定です。これは私が今持っているものです。

<!DOCTYPE html>
<html>
<head>
    <title>Bootstrap Tree View</title>
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
    <link href="./TreeView_files/bootstrap-treeview.css" rel="stylesheet">
</head>
<body>
    <div class="container">
        <h1>Bootstrap Tree View - DOM Tree</h1>
        <br/>
        <div class="row">
            <div class="col-sm-12">
                <label for="treeview"></label>
                <div id="treeview"/>
            </div>
        </div>
    </div>
    <script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
    <script src="./TreeView_files/bootstrap-treeview.js"></script>
    <script type="text/javascript">

        function buildDomTree() {
            var tree = [
            {
                text: "Parent 1",
                nodes: [
                {
                    text: "Child 1",
                    nodes: [
                    {
                        text: "Grandchild 1"
                    },
                    {
                        text: "Grandchild 2"
                    }
                    ]
                },
                {
                    text: "Child 2"
                }
                ]
            },
            {
                text: "Parent 2"
            },
            {
                text: "Parent 3"
            },
            {
                text: "Parent 4"
            },
            {
                text: "Parent 5"
            }
            ];
            return tree;
        }

        $(function() {

            var options = {
                bootstrap2: false, 
                showTags: true,
                levels: 5,
                data: buildDomTree()
            };

            $('#treeview').treeview(options);
        });
    </script>
</body>

Treeviewは4レベル深くなる可能性があり、ノードがクリックされるたびに次のレベルのJSONをフェッチしたいと思います。したがって、「親5」をクリックすると、サブノードがポップアウトするはずです。ノードを動的に追加する方法がわかりません。どんな助けでも本当にありがたいです。

6
Crimson7

リクエストに応じて回答:それを行う方法を見つけましたが、少し非効率的です。私が行ったことは、展開されたすべてのノードの状態を保持し、ノードをクリックして展開すると、HTTPリクエストを作成し、新しいノードを古いノードに追加し、ツリー全体を再描画して再展開します。以前に拡張されたすべてのノード。これは非効率的であることはわかっていますが、本質的にツリー全体を自分で再作成せずに見つけることができる唯一の方法です(これは単なる栄光の再帰アプリケーションです)。

質問を投稿したときに実行したコードは次のとおりです。明らかに改善の余地があります。

var expandedNodes = [];
var tree = [];

$(function()
{
    $.post("http://localhost:8000/getLevel1", function( data ) 
    {
        var JSObject = JSON.parse(data);

        for (j in JSObject)
            tree.Push(JSObject[j]);

        createTree();
    });
});

function createTree(){

    var options = {
        bootstrap2: false, 
        showTags: true,
        levels: 0,
        data: tree,
        expandIcon: 'fa fa-chevron-right',
        collapseIcon: 'fa fa-chevron-down',
        onNodeExpanded: nodeExpand,
        onNodeCollapsed: nodeCollapse,
        onNodeSelected: nodeSelect,
        onNodeUnselected: nodeUnselect
    }
    $('#treeview').treeview(options);
    for (node in expandedNodes)
        $('#treeview').treeview('expandNode', [ expandedNodes[node], { levels: 0, silent: true } ]);
    $('#treeview').treeview('expandNode', 0, { silent: true } );
};


function nodeExpand(event, data)
{
    expandedNodes.Push(data.nodeId);
    var requestObject = []
    requestObject.Push(data.text);

    var parent, dummy = data;
    while ((parent = $('#treeview').treeview('getParent', dummy.nodeId))["nodeId"] != undefined)
        {
        requestObject.Push(parent.text);
        dummy = parent;
    }

    $.post("http://localhost:8000/getNode?param=" + JSON.stringify(requestObject), function(retVal) 
    {
        var JSObject = JSON.parse(retVal);
        var node = findNode(requestObject);
        node.nodes = JSObject;
        createTree();
    });
}

function nodeCollapse(event, data)
{
    var index = expandedNodes.indexOf(data.nodeId);
    if (index > -1) 
        expandedNodes.splice(index, 1);
}

function nodeSelect(event, data)
{
    if (data.state.expanded == true)
        $('#treeview').treeview('collapseNode', data.nodeId);
    else
        $('#treeview').treeview('expandNode', data.nodeId);
    //$('#treeview').treeview('unselectNode', [ data.nodeId, { silent: true } ]);
}

function nodeUnselect(event, data)
{
}

function findNode(array)
{
    var searchIn = tree; //array
    var lastFound = tree;
    for (var i = array.length - 1; i >= 0; i--)
        {
        var obj = searchInObject(searchIn, array[i]);
        searchIn = obj.nodes;
        lastFound = obj;
    }

    return lastFound;
}

function searchInObject(objectArray, string)
{
    for (var index in objectArray)
        if (objectArray[index].text == string)
            return objectArray[index];
}

$(document).ready(function () {
    var trigger = $('.hamburger'),
    overlay = $('.overlay'),
    isClosed = false;
    hamburger_cross();
    $('#wrapper').toggleClass('toggled');

    trigger.click(function () {
        hamburger_cross();      
    });

    function hamburger_cross() {

        if (isClosed == true) {          
            overlay.hide();
            trigger.removeClass('is-open');
            trigger.addClass('is-closed');
            isClosed = false;
            $('#open_arrow').removeClass('fa-chevron-circle-left').addClass('fa-chevron-circle-right');
        } else {   
            overlay.show();
            trigger.removeClass('is-closed');
            trigger.addClass('is-open');
            isClosed = true;
            $('#open_arrow').removeClass('fa-chevron-circle-right').addClass('fa-chevron-circle-left');
        }
    }

    $('[data-toggle="offcanvas"]').click(function () {
        $('#wrapper').toggleClass('toggled');

    });  
});

関心のあるポイントは、nodeExpandおよびcreateTreeメソッドです。

1
Crimson7