如何在 AngularJS + Bootstrap 中显示可折叠树

IT技术 javascript angularjs twitter-bootstrap collapse
2021-03-09 00:44:37

我正在构建一个网络应用程序,我需要在其中使用列表显示一棵树。我的基本结构是这样的:

* Node 1
    * Node 1.1
        * Node 1.1.1
            * Node 1.1.1.1
        * Node 1.1.2
    * Node 1.2

http://jsfiddle.net/QffFm/1/

我试图在 angular 或 bootstrap 中找到一些我可以使用的东西:

  • 在列表的第一个视图中,它被扩展到第三层。在我的小提琴中,我想看到节点 1、节点 1.1、节点 1.1.1、节点 1.1.2 和节点 1.2(除了第 4 层 - 节点 1.1.1.1)
  • 单击列表样式图标(不是节点的单词名称)时,节点会折叠或展开
  • 理想情况下,我希望图标也能根据项目是否展开而改变。如果下面有更多,则为右箭头,如果已展开则为向下箭头,如果没有子项,则可能是常规列表项

我对 AngularJS 很陌生,对 Bootstrap 也很陌生。我看到 Angular 有一个手风琴功能,它似乎不能完全处理我需要的一切。

在我将大量逻辑编码到处理不同情况的 Web 应用程序中之前,我希望获得有关最佳方法的一些指导。我认为这一定是一个常见问题,所以也许有一些现成的东西可以使用。任何指导将不胜感激。

HTML代码:

<div ng-app="myApp" ng-controller="controller">
    <my-directive></my-directive>
    <table style="width: 100%"><tbody><td>
        <tree items="tree"></tree>
    </td></tbody></table>
</div>

角度代码:

var app = angular.module('myApp', []);

app.controller('controller', function ($scope){ 

    $scope.tree=[{"name":"Node 1","items":[{"name":"Node 1.1","items":[{"name":"Node 1.1.1","items":[{"name":"Node 1.1.1.1","items":[]}]},{"name":"Node 1.1.2","items":[]}]},{"name":"Node 1.2","items":[]}]}];

});
app.directive('tree', function() {
    return {
        template: '<ul><tree-node ng-repeat="item in items"></tree-node></ul>',
        restrict: 'E',
        replace: true,
        scope: {
            items: '=items',
        }
    };
});

app.directive('treeNode', function($compile) {
    return { 
        restrict: 'E',
        template: '<li >{{item.name}}</li>',
        link: function(scope, elm, attrs) {
        if (scope.item.items.length > 0) {
            var children = $compile('<tree items="item.items"></tree>')(scope);
            elm.append(children);
        }
    }
    };
});
1个回答

在以下示例中,我使用了:

  • 引导程序
  • AngularJS 递归ng-include(见第二个例子)递归指令
  • jQuery(将来会尽量避免)

演示 1 ( ng-include)Plunker

在此处输入图片说明

从这个模型:

 $scope.displayTree =
            [{
            "name": "Root",
            "type_name": "Node",
            "show": true,
            "nodes": [{
                "name": "Loose",
                "group_name": "Node-1",
                "show": true,
                "nodes": [{
                    "name": "Node-1-1",
                    "device_name": "Node-1-1",
                    "show": true,
                    "nodes": []
                }, {
                    "name": "Node-1-2",
                    "device_name": "Node-1-2",
                    "show": true,
                    "nodes": []
                }, {
                    "name": "Node-1-3",
                    "device_name": "Node-1-3",
                    "show": true,
                    "nodes": []
                }]
            }, {
                "name": "God",
                "group_name": "Node-2",
                "show": true,
                "nodes": [{
                    "name": "Vadar",
                    "device_name": "Node-2-1",
                    "show": true,
                    "nodes": []
                }]
            }, {
                "name": "Borg",
                "group_name": "Node-3",
                "show": true,
                "nodes": []
            }, {
                "name": "Fess",
                "group_name": "Node-4",
                "show": true,
                "nodes": []
            }]
        }];
        [{
            "name": "Android",
            "type_name": "Android",
            "icon": "icon-android icon-3",
            "show": true,
            "nodes": []
        }];
    }

第二个示例基于 2 个指令:

app.directive('nodeTree', function() {
      return {
        template: '<node ng-repeat="node in tree"></node>',
        replace: true,
        transclude: true,
        restrict: 'E',
        scope: {
          tree: '=ngModel'
        }
      };
});

app.directive('node', function($compile) {
  return { 
    restrict: 'E',
    replace:true,
     templateUrl: 'the-tree.html',
    link: function(scope, elm, attrs) {
    
      // ....     
     
      if (scope.node.children.length > 0) {
        var childNode = $compile('<ul ><node-tree ng-model="node.children"></node-tree></ul>')(scope)
        elm.append(childNode);
      }
    }
  };
}); 

(还添加了一些复选框:))

演示 2 Plunker

它的外观:

在此处输入图片说明

@im1dermike 对,资源 URL 已更改,但您可以更改并使其工作。我将很快更新这两个演示。谢谢
2021-04-26 00:44:37
@jackyrudetsky 我建议您针对此问题提出新问题,请在此处发布链接以供参考。谢谢
2021-04-28 00:44:37
@jackyrudetsky 添加$('.tree ul:not(:has(*))').css('display', 'none')链接:plnkr.co/edit/4623L8LTmOyPPekBUyrh?p=preview
2021-05-06 00:44:37
@MaximShoustin 是否可以将此水平转换。我把 css 改成了这个,但它没有你在这里看到的那么好
2021-05-18 00:44:37