是否可以使用Angular创建树视图?

Jon*_*ams 176 angularjs

我希望在Web应用程序中以树形结构显示数据.我希望使用Angular来完成这项任务.

看起来ng-repeat将允许我遍历节点列表,但是当给定节点的深度增加时,我怎么能进行嵌套呢?

我尝试了以下代码,但HTML的自动转义阻止了它的工作.另外,结束ul标签位置错误.

我很确定我完全以错误的方式解决这个问题.

有任何想法吗?

gan*_*raj 230

看看这个小提琴

原文:http: //jsfiddle.net/brendanowen/uXbn6/8/

更新:http://jsfiddle.net/animaxf/uXbn6/4779/

这应该可以让您了解如何显示tree like structure使用角度.它是一种在html中使用递归!

  • 为什么不说[你的来源](https://groups.google.com/d/msg/angular/TbpjE-5XEM0/yUi8wqc7sWoJ)?你在那个帖子中写了一篇文章,现在你在这里发布了一个你自己名字的网址? (94认同)
  • 我真的厌倦了人们经常评论这个URL有我的名字(因此它是抄袭!).不幸的是,jsfiddle是如何工作的.如果您在登录时分叉,它会保留您的用户名.说我现在已经链接到原始URL.如果错误,请给出答案 - 在这种情况下,答案恰好是正确的,我所拥有的备份URL似乎包含了我的名字. (43认同)
  • 老兄,你应该陈述你的来源. (10认同)
  • 这是一个相同的版本(我认为),除了它加载得更快(至少对我来说),因为它没有在CSS部分中内联的Twitter Bootstrap.http://jsfiddle.net/brendanowen/uXbn6/8/ (5认同)
  • 我刚刚将崩溃和展开按钮添加到您的版本:http://jsfiddle.net/uXbn6/639/ (5认同)
  • 在这里使用[指令](http://docs.angularjs.org/guide/directive)会有什么好处吗? (4认同)

Nic*_*ins 77

如果您使用的是Bootstrap CSS ...

我已经基于Bootstrap"nav"列表为AngularJS创建了一个简单的可重用树控件(指令).我添加了额外的缩进,图标和动画.HTML属性用于配置.

它不使用递归.

我叫它angular-bootstrap-nav-tree(上口名字,你不觉得吗?)

有一个例子在这里,源是在这里.

  • 是的,它使用新动画的东西...需要Angular 1.1.5(我想?) (3认同)
  • 更新:它现在可以使用Angular 1.1.5或Angular 1.2.0,也适用于Bootsrap 2或Bootstrap 3 (3认同)
  • @Nick Perkins - 请解释为什么你的angular-bootstrap-nav-tree没有用于移除分支/节点的API.至少,通过快速检查来源,并检查您的测试/示例,似乎没有那个选项.这肯定是一个重要的遗漏? (2认同)

Mar*_*ijk 35

在制作这样的东西时,最好的解决方案是递归指令.但是,当你制作这样的指令时,你会发现AngularJS进入无限循环.

解决方案是让指令在编译事件期间删​​除元素,并手动编译并在链接事件中添加它们.

我在这个帖子中发现了这个,并将这个功能抽象为一个服务.

module.factory('RecursionHelper', ['$compile', function($compile){
    return {
        /**
         * Manually compiles the element, fixing the recursion loop.
         * @param element
         * @param [link] A post-link function, or an object with function(s) registered via pre and post properties.
         * @returns An object containing the linking functions.
         */
        compile: function(element, link){
            // Normalize the link parameter
            if(angular.isFunction(link)){
                link = { post: link };
            }

            // Break the recursion loop by removing the contents
            var contents = element.contents().remove();
            var compiledContents;
            return {
                pre: (link && link.pre) ? link.pre : null,
                /**
                 * Compiles and re-adds the contents
                 */
                post: function(scope, element){
                    // Compile the contents
                    if(!compiledContents){
                        compiledContents = $compile(contents);
                    }
                    // Re-add the compiled contents to the element
                    compiledContents(scope, function(clone){
                        element.append(clone);
                    });

                    // Call the post-linking function, if any
                    if(link && link.post){
                        link.post.apply(null, arguments);
                    }
                }
            };
        }
    };
}]);
Run Code Online (Sandbox Code Playgroud)

使用此服务,您可以轻松地创建树指令(或其他递归指令).以下是树指令的示例:

module.directive("tree", function(RecursionHelper) {
    return {
        restrict: "E",
        scope: {family: '='},
        template: 
            '<p>{{ family.name }}</p>'+
            '<ul>' + 
                '<li ng-repeat="child in family.children">' + 
                    '<tree family="child"></tree>' +
                '</li>' +
            '</ul>',
        compile: function(element) {
            return RecursionHelper.compile(element);
        }
    };
});
Run Code Online (Sandbox Code Playgroud)

有关演示,请参阅此Plunker.我最喜欢这个解决方案,因为:

  1. 你不需要一个特殊的指令,使你的HTML不那么干净.
  2. 递归逻辑被抽象到RecursionHelper服务中,因此您可以保持指令清洁.

更新:添加了对自定义链接功能的支持.


Kal*_*nam 17

angular-ui-tree似乎对我有好处


sav*_*nda 14

以下是使用递归指令的示例:http://jsfiddle.net/n8dPm/ 取自https://groups.google.com/forum/#!topic/angular/vswXTes_FtM

module.directive("tree", function($compile) {
return {
    restrict: "E",
    scope: {family: '='},
    template: 
        '<p>{{ family.name }}</p>'+
        '<ul>' + 
            '<li ng-repeat="child in family.children">' + 
                '<tree family="child"></tree>' +
            '</li>' +
        '</ul>',
    compile: function(tElement, tAttr) {
        var contents = tElement.contents().remove();
        var compiledContents;
        return function(scope, iElement, iAttr) {
            if(!compiledContents) {
                compiledContents = $compile(contents);
            }
            compiledContents(scope, function(clone, scope) {
                     iElement.append(clone); 
            });
        };
    }
};
});
Run Code Online (Sandbox Code Playgroud)


GFo*_*y83 5

基于原始源的另一个示例,已经存在示例树结构(更容易看到它如何工作IMO)和搜索树的过滤器:

的jsfiddle