递归菜单指令

6
我是一名有用的助手,可以为您翻译文本。
我正在尝试使用AngularJS创建一个递归菜单,但是我一直收到以下错误提示:Maximum call stack size exceeded 我的指令:
angular.module("application").directive("navigation", [function () {
            return {
                restrict : 'E',
                replace : true,
                scope : {
                    menu : '='
                },
                template : '<ul><navigation-item ng-repeat="item in menu" submenu="item"></navigation-item></ul>',
                link : function ($scope, elem, attrs) {}
            }
        }
    ]);


angular.module("application").directive("navigationItem", [function () {

            return {
                restrict : 'E',
                replace : true,
                scope : {
                    submenu : '='
                },
                template : '<li>{{ submenu }}<navigation menu="submenu.Children"></navigation></li>',
                link : function ($scope, elem, attrs) {}
            }
        }
    ]);

我的控制器:

app.controller('myController', ['$scope', function (ng) {
        ng.menu = [{
            Id : 1,
            Nome : "Contact",
            Children : [{
                Nome : "Testing",
                Children : []
            }]
        }];
    }
]);

下面是翻译的结果:

这是我的使用方法:

<navigation menu="menu"></navigation>

http://jsfiddle.net/7sq3n/

2个回答

15

这里有两个问题:

  1. 你不需要使用两个指令
  2. 我怀疑你需要使用指令的编译函数来使其正常工作,因为你在指令自身的模板中使用了该指令本身,你还需要使用可注入的 $compile

我在模板中使用了 ngIf 指令,你不必这样做,我只是想让你知道并警告你需要使用 AngularJS 1.1.5+ 才能使用该指令。

这是我用过的一个 JSFiddle: http://jsfiddle.net/mikeeconroy/7sq3n/6/

.directive("navigation", ['$log','$compile',function ($log,$compile) {

    return {
        restrict: 'E',
        replace: true,
        scope: {
            menu: '='
        },
        template: '<ul><li ng-repeat="item in menu">{{item.Name}}<span ng-if="item.Children.length > 0"><navigation menu="item.Children"></navigation></span></li></ul>',
        compile: function (el) {
            var contents = el.contents().remove();
            return function(scope,el){
                $compile(contents)(scope,function(clone){
                    el.append(clone);
                });
            };
        }
    };

我在这里稍微借鉴了一些帮助:Angular 指令中的递归

更新:http://jsfiddle.net/mikeeconroy/Z6sG9/2/ 解决多个根元素问题


1
一个根元素时可以正常工作,但当我尝试使用两个根元素时,它没有显示子节点。Fiddle链接:http://jsfiddle.net/7sq3n/7/ - 有什么建议吗? - WeaselBr
正在查看,非常奇怪。 - m.e.conroy
1
我不知道为什么分解$compile语句会使其工作,但它确实可以,也许是因为有一些幕后的竞争情况发生了。 - m.e.conroy

1
使用Angular和Bootstrap创建具有动态数据的动态递归导航菜单(导航栏)。

http://plnkr.co/edit/YqGcmcH6VQqr3rxOswnb

    <div ng-app="headerMenuApp">
    <div ng-controller="headerMenuListController">
        <nav id="headerNavigationMenuContainer" class="navbar navbar-default">
            <div class="container-fluid">

                <!-- Non-collapsing right-side menu items -->
                <div class="navbar-header pull-right">
                    <ul class="nav pull-left navbar-nav text-nowrap">
                        <li class="dropdown pull-right">
                            <a href="#" class="dropdown-toggle navbar-icon" data-toggle="dropdown" role="button" aria-expanded="false"><i class="fa fa-question-circle"></i> &nbsp; Help <span class="caret"></span></a>
                            <ul class="dropdown-menu" role="menu">
                                <li><a href="#">Live Chat</a></li>
                                <li><a href="#">Help Topics</a></li>
                            </ul>
                        </li>
                    </ul>
                </div>

                <!-- Collapsing left-side menu items -->
                <div class="navbar-header">
                    <button type="button" class="navbar-toggle collapsed pull-left" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar" ng-init="navCollapsed = true" ng-click="navCollapsed = !navCollapsed">
                        <span class="sr-only">Toggle navigation</span>
                        <span class="icon-bar"></span>
                        <span class="icon-bar"></span>
                        <span class="icon-bar"></span>
                    </button>
                    <a class="navbar-brand" href="#">Logo</a>
                </div>

                <div id="navbar" class="collapse navbar-collapse" ng-class="!navCollapsed && 'in'">
                    <ul class="nav navbar-nav text-nowrap">
                        <leaf ng-repeat='leaf in tree' leaf='leaf'></leaf>
                    </ul>
                </div>

            </div>
        </nav>
    </div>
</div>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接