7

今朝、優れたjstreejQueryUIプラグインに遭遇しました。一言で言えば-素晴らしい!それは使いやすく、スタイリングしやすく、箱に書かれていることを実行します。私がまだ理解できていないことの1つは、これです。私のアプリでは、常に1つのノードのみが展開されるようにしたいのです。つまり、ユーザーが[+]ボタンをクリックしてノードを展開すると、以前に展開されたノードはすべてサイレントに折りたたまれます。かなり長いツリービューのコンテナdivがオーバーフロー時に醜いスクロールバーを作成するのを防ぎ、ユーザーの「選択の過負荷」を回避するために、これを部分的に行う必要があります。

これを行うにはいくつかの方法があると思いますが、良いが簡潔なjstreeドキュメントは、これを行う正しい方法を特定するのに役立ちませんでした。助けていただければ幸いです。

4

4 に答える 4

5

jsTreeは素晴らしいですが、そのドキュメントはかなり密集しています。私は最終的にそれを理解したので、これがこのスレッドに遭遇した人のための解決策です。

まず、open_nodeイベントを問題のツリーにバインドする必要があります。の線に沿った何か

$("tree").jstree({"themes":objTheme,"plugins":arrPlugins,"core":objCore}).
bind("open_node.jstree",function(event,data){closeOld(data)}); 

つまり、treeviewインスタンスを構成してから、open_nodeイベントをバインドします。ここでは、closeOld関数を呼び出して、必要なジョブを実行しています。開いている可能性のある他のノードをすべて閉じます。関数はそのようになります

function closeOld(data)
{
    var nn = data.rslt.obj;
    var thisLvl = nn;
    var levels = new Array();
    var iex = 0;
    while (-1 != thisLvl)
    {
        levels.push(thisLvl);
        thisLvl = data.inst._get_parent(thisLvl);
        iex++;
    }

    if (0 < ignoreExp)
    {
        ignoreExp--;
        return;
    }

    $("#divElements").jstree("close_all");
    ignoreExp = iex;
    var len = levels.length - 1;
    for (var i=len;i >=0;i--) $('#divElements').jstree('open_node',levels[i]);
}

これにより、展開されたばかりのノードのネストレベルに関係なく、他のすべてのノードのフォールディングが正しく処理されます。

関連する手順の簡単な説明

  • 最初に、最上位ノード(jstreeの場合は-1)に到達するまでツリービューをステップアップし、プロセスで検出されたすべての祖先ノードを配列レベルで記録するようにします。
  • 次に、ツリービューのすべてのノードを折りたたみます
  • 次に、 levels配列内のすべてのノードを再展開します。そうしている間、このコードを再度実行したくありません。これを防ぐために、グローバルignoreEx変数をレベル内のノード数に設定します
  • 最後に、ノードをレベルごとにステップスルーし、各ノードを展開します
于 2012-08-28T12:33:09.187 に答える
2

上記の答えは何度も何度もツリーを構築します。以下のコードは、すでに開いているノードを開いて折りたたむため、ツリーを再度構築することはありません。

.bind("open_node.jstree",function(event,data){
        closeOld(data);
        });

closeOld関数には次のものが含まれます。

function closeOld(data)
{
    if($.inArray(data.node.id, myArray)==-1){
            myArray.push(data.node.id);
            if(myArray.length!=1){
                var arr =data.node.id+","+data.node.parents;
                var res = arr.split(",");
                var parentArray = new Array();
                var len = myArray.length-1;
                for (i = 0; i < res.length; i++) {
                    parentArray.push(res[i]);
                }
                for (var i=len;i >=0;i--){
                    var index = $.inArray(myArray[i], parentArray);
                if(index==-1){
                    if(data.node.id!=myArray[i]){
                    $('#jstree').jstree('close_node',myArray[i]);
                        delete myArray[i];
                    }
                }
                }
        }
    }
于 2015-04-03T12:28:09.593 に答える
1

jstree3.3.2のさらに別の例。アンダースコアlibを使用し、ソリューションをjqueryまたはvanilllajsに自由に適合させます。

$(function () {
    var tree = $('#tree');
    tree.on('before_open.jstree', function (e, data) {
        var remained_ids = _.union(data.node.id, data.node.parents);
        var $tree = $(this);
        _.each(
                $tree
                    .jstree()
                    .get_json($tree, {flat: true}),
                function (n) {
                    if (
                        n.state.opened &&
                        _.indexOf(remained_ids, n.id) == -1
                    ) {
                        grid.jstree('close_node', n.id);
                    }
                }
        );
    });
    tree.jstree();
});
于 2016-10-20T03:02:44.430 に答える
1

イベント「before_open」を使用してすべてのノードを閉じるだけで、ツリーのレベルが1つだけになり、それが必要かどうかはわかりません。

$('#dtree').on('before_open.jstree', function(e, data){
    $("#dtree").jstree("close_all");
});
于 2018-02-28T19:52:16.623 に答える