Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 带ng重复的递归_Javascript_Angularjs_Recursion_Angularjs Ng Repeat - Fatal编程技术网

Javascript 带ng重复的递归

Javascript 带ng重复的递归,javascript,angularjs,recursion,angularjs-ng-repeat,Javascript,Angularjs,Recursion,Angularjs Ng Repeat,在一个基于付费网站主题的Angular应用程序中,我的侧菜单中的项目具有以下数据结构。数据结构是我自己的,菜单是从原始菜单视图派生的,所有项目都在ul硬编码中 在SidebarController.js中: $scope.menuItems = [ { "isNavItem": true, "href": "#/dashboard.html", "text": "Dashboard" }, { "isNavI

在一个基于付费网站主题的Angular应用程序中,我的侧菜单中的项目具有以下数据结构。数据结构是我自己的,菜单是从原始菜单视图派生的,所有项目都在
ul
硬编码中

SidebarController.js
中:

$scope.menuItems = [
    {
        "isNavItem": true,
        "href": "#/dashboard.html",
        "text": "Dashboard"
    },
    {
        "isNavItem": true,
        "href": "javascript:;",
        "text": "AngularJS Features",
        "subItems": [
            {
                "href": "#/ui_bootstrap.html",
                "text": " UI Bootstrap"
            },
            ...
        ]
    },
    {
        "isNavItem": true,
        "href": "javascript:;",
        "text": "jQuery Plugins",
        "subItems": [
            {
                "href": "#/form-tools",
                "text": " Form Tools"
            },
            {
                "isNavItem": true,
                "href": "javascript:;",
                "text": " Datatables",
                "subItems": [
                    {
                        "href": "#/datatables/managed.html",
                        "text": " Managed Datatables"
                    },
                    ...
                ]
            }
        ]
    }
];
然后,我将以下局部视图绑定到该模型,如下所示:

<ul class="page-sidebar-menu" data-keep-expanded="false" data-auto-scroll="true" data-slide-speed="200" ng-class="{'page-sidebar-menu-closed': settings.layout.pageSidebarClosed}">
    <li ng-repeat="item in menuItems" ng-class="{'start': item.isStart, 'nav-item': item.isNavItem}">
        <a href="{{item.href}}" ng-class="{'nav-link nav-toggle': item.subItems && item.subItems.length > 0}">
            <span class="title">{{item.text}}</span>
        </a>
        <ul ng-if="item.subItems && item.subItems.length > 0" class="sub-menu">
            <li ng-repeat="item in item.subItems" ng-class="{'start': item.isStart, 'nav-item': item.isNavItem}">
                <a href="{{item.href}}" ng-class="{'nav-link nav-toggle': item.subItems && item.subItems.length > 0}">
                    <span class="title">{{item.text}}</span>
                </a>
            </li>
        </ul>
    </li>
</ul>
注意在模型中看不到的视图绑定中可能有
$scope
属性,反之亦然,但这是因为为了简洁起见,我对它们进行了编辑。 现在,由于第二级
li
不包含其自身
子项的条件
ul
,因此不会呈现
Datatable
菜单项下的子项


如何创建递归绑定到模型的视图或模板(或两者),以便呈现所有子项的所有子项?这通常最多只有四个级别。

您可以简单地使用ng include生成分部并递归调用它: 部分应该是这样的:

<ul>
    <li ng-repeat="item in item.subItems">
      <a href="{{item.href}}" ng-class="{'nav-link nav-toggle': item.subItems && item.subItems.length > 0}">
          <span class="title">{{item.text}}</span>
      </a>
      <div ng-switch on="item.subItems.length > 0">
        <div ng-switch-when="true">
          <div ng-init="subItems = item.subItems;" ng-include="'partialSubItems.html'"></div>  
        </div>
      </div>
    </li>
</ul>
以及您的html:

<ul class="page-sidebar-menu" data-keep-expanded="false" data-auto-scroll="true" data-slide-speed="200" ng-class="{'page-sidebar-menu-closed': settings.layout.pageSidebarClosed}">
    <li ng-repeat="item in menuItems" ng-class="{'start': item.isStart, 'nav-item': item.isNavItem}">
        <a href="{{item.href}}" ng-class="{'nav-link nav-toggle': item.subItems && item.subItems.length > 0}">
            <span class="title">{{item.text}}</span>
        </a>
        <ul ng-if="item.subItems && item.subItems.length > 0" class="sub-menu">

            <li ng-repeat="item in item.subItems" ng-class="{'start': item.isStart, 'nav-item': item.isNavItem}">
                 <a href="{{item.href}}" ng-class="{'nav-link nav-toggle': item.subItems && item.subItems.length > 0}">
                    <span class="title">{{item.text}}</span>
                </a>

                 <div ng-switch on="item.subItems.length > 0">
                    <div ng-switch-when="true">
                      <div ng-init="subItems = item.subItems;" ng-include="'newpartial.html'"></div>  
                    </div>
                </div>

            </li>
        </ul>
    </li>
</ul>
这是正在工作的plunker

如果您的意图是绘制一个子项级别不确定的菜单,那么一个好的实现可能是生成一个指令

有了指令,你就可以对菜单进行更多的控制

我创建了一个带有完整递归的基本exepmle,在上,您可以在同一页面上看到多个菜单的简单实现,在其中一个菜单上可以看到多个级别,请参见此

代码:

.directive('myMenu', ['$parse', function($parse) {
    return {
      restrict: 'A',
      scope: true,
      template:
        '<li ng-repeat="item in List" ' +
        'ng-class="{\'start\': item.isStart, \'nav-item\': item.isNavItem}">' +
        '<a href="{{item.href}}" ng-class="{\'nav-link nav-toggle\': item.subItems && item.subItems.length > 0}">'+
        '<span class="title"> {{item.text}}</span> ' +
        '</a>'+
        '<ul my-menu="item.subItems" class="sub-menu"> </ul>' +
        '</li>',
      link: function(scope,element,attrs){
        //this List will be scope invariant so if you do multiple directive 
        //menus all of them wil now what list to use
        scope.List = $parse(attrs.myMenu)(scope);
      }
    }
}])
<ul class="page-sidebar-menu" 
    data-keep-expanded="false" 
    data-auto-scroll="true" 
    data-slide-speed="200" 
    ng-class="{'page-sidebar-menu-closed': settings.layout.pageSidebarClosed}"
    my-menu="menuItems">
</ul>
激光源角波导

编辑


正如Mathew Berg所建议的那样,如果子项列表为空,那么如果不想包含ul元素,那么可以将ul更改为类似的形式,例如,Rahul Arora的答案很好,请参见下面的类似示例。我要做的一个改变是使用组件而不是ng include。有关示例,请参见:

app
.component('recursiveItem'{
绑定:{

item:“您只需包含一个javascript模板和使用ng include的模板include就可以实现这一点

定义javascript模板

<script type="text/ng-template" id="menu.html">...</script>
。。。
包括:

<div ng-if="item.subItems.length" ng-include="'menu.html'"></div>

示例:在这个示例中,我使用了基本html,没有任何类,您可以根据需要使用这些类。我只是展示了基本的递归结构

html中

<ul>
    <li ng-repeat="item in menuItems">
      <a href="{{item.href}}">
        <span>{{item.text}}</span>
      </a>
      <div ng-if="item.subItems.length" ng-include="'menu.html'"></div>
    </li>
</ul>


<script type="text/ng-template" id="menu.html">
   <ul>
      <li ng-repeat="item in item.subItems">
        <a href="{{item.href}}">
          <span>{{item.text}}</span>
        </a>
        <div ng-if="item.subItems.length" ng-include="'menu.html'"></div>
      </li>
   </ul>
</script>

为了在angularJS中进行递归,我希望使用angularJS的基本功能和I.e指令

index.html

<rec-menu menu-items="menuItems"></rec-menu>

recMenu.html

<ul>
  <li ng-repeat="item in $ctrl.menuItems">
    <a ng-href="{{item.href}}">
      <span ng-bind="item.text"></span>
    </a>
    <div ng-if="item.menuItems && item.menuItems.length">
      <rec-menu menu-items="item.menuItems"></rec-menu>
    </div>
  </li>
</ul>
recMenu.html

angular.module('myApp').component('recMenu', {
  templateUrl: 'recMenu.html',
  bindings: {
    menuItems: '<'
  }
});
angular.module('myApp')。组件('recMenu'{
templateUrl:'recMenu.html',
绑定:{

MENUTION: '

在使用带有<代码> NG的模板之前,包含或编写您自己的指令,我建议您考虑使用现有的树组件实现。 原因是,根据您的描述,这正是您所需要的。您有一个层次结构的树状数据结构,您希望显示它。我听上去很明显,您需要一个树状组件

请看一下以下实现(首选第一种):


以上所有操作只需要对模型进行轻微调整,或者使用代理模型

如果您坚持自己实现它(无论您最终如何实现它,基本上您仍将从头开始实现树组件),我建议您采用前面答案中提出的指导方法。我将这样做:

JS
var-app=angular.module('MyApp',[]);
app.controller('MyCtrl',函数($scope,$window){
$scope.menuItems=[
{
“isNavItem”:正确,
“href”:“#/dashboard.html”,
“文本”:“仪表板”
},
{
“isNavItem”:正确,
“href”:“javascript:;”,
“文本”:“AngularJS功能”,
“分项”:[
{
“href”:“#/ui_bootstrap.html”,
“文本”:“UI引导”
}
]
},
{
“isNavItem”:正确,
“人力资源
<ul>
  <li ng-repeat="item in $ctrl.menuItems">
    <a ng-href="{{item.href}}">
      <span ng-bind="item.text"></span>
    </a>
    <div ng-if="item.menuItems && item.menuItems.length">
      <rec-menu menu-items="item.menuItems"></rec-menu>
    </div>
  </li>
</ul>
angular.module('myApp').component('recMenu', {
  templateUrl: 'recMenu.html',
  bindings: {
    menuItems: '<'
  }
});
var app=angular.module('MyApp', []);

app.controller('MyCtrl', function($scope, $window) {
  $scope.menuItems = [
    {
        "isNavItem": true,
        "href": "#/dashboard.html",
        "text": "Dashboard"
    },
    {
        "isNavItem": true,
        "href": "javascript:;",
        "text": "AngularJS Features",
        "subItems": [
            {
                "href": "#/ui_bootstrap.html",
                "text": " UI Bootstrap"
            }
        ]
    },
    {
        "isNavItem": true,
        "href": "javascript:;",
        "text": "jQuery Plugins",
        "subItems": [
            {
                "href": "#/form-tools",
                "text": " Form Tools"
            },
            {
                "isNavItem": true,
                "href": "javascript:;",
                "text": " Datatables",
                "subItems": [
                    {
                        "href": "#/datatables/managed.html",
                        "text": " Managed Datatables"
                    }
                ]
            }
        ]
    }];
});

app.directive('myMenu', ['$compile', function($compile) {
  return {
    restrict: 'E',
    scope: {
      menu: '='      
    },
    replace: true,
    link: function(scope, elem, attrs) {
      var items = $compile('<my-menu-item ng-repeat="item in menu" menu-item="item"></my-menu-item>')(scope);

      elem.append(items);
    },
    template: '<ul class="page-sidebar-menu" data-keep-expanded="false" data-auto-scroll="true" data-slide-speed="200" ng-class="{\'page-sidebar-menu-closed\': settings.layout.pageSidebarClosed}"></ul>'
  };
}]);

app.directive('myMenuItem', [function() {
  return {
    restrict: 'E',
    scope: {
      menuItem: '='
    },
    replace: true,
    template: '<li ng-class="{\'start\': item.isStart, \'nav-item\': item.isNavItem}"><a href="{{menuItem.href}}" ng-class="{\'nav-link nav-toggle\': menuItem.subItems && menuItem.subItems.length > 0}"> <span class="title">{{menuItem.text}}</span></a><my-menu menu="menuItem.subItems"></my-menu></li>'

  };
}]);
<div ng-app="MyApp" ng-controller="MyCtrl">
  <my-menu menu="menuItems"></my-menu>
</div>
<script type="text/ng-template"  id="tree_item_renderer.html">
{{data.name}}
<button ng-click="add(data)">Add node</button>
<button ng-click="delete(data)" ng-show="data.nodes.length > 0">Delete nodes</button>
<ul>
    <li ng-repeat="data in data.nodes" ng-include="'tree_item_renderer.html'"></li>
</ul>
  angular.module("myApp", []).
controller("TreeController", ['$scope', function($scope) {
    $scope.delete = function(data) {
        data.nodes = [];
    };
    $scope.add = function(data) {
        var post = data.nodes.length + 1;
        var newName = data.name + '-' + post;
        data.nodes.push({name: newName,nodes: []});
    };
    $scope.tree = [{name: "Node", nodes: []}];
}]);
angular.module("myApp", []).controller("TreeController", ['$scope',function($scope) {


    $scope.menuItems = [{
      "isNavItem": true,
      "href": "#/dashboard.html",
      "text": "Dashboard"
    }, {
      "isNavItem": true,
      "href": "javascript:;",
      "text": "AngularJS Features",
      "subItems": [{
        "href": "#/ui_bootstrap.html",
        "text": " UI Bootstrap"
      }, {
        "isNavItem": true,
        "href": "javascript:;",
        "text": "AngularJS Features",
        "subItems": [{
          "href": "#/ui_bootstrap.html",
          "text": " UI Bootstrap"
        }]
      }]
    }, {
      "isNavItem": true,
      "href": "javascript:;",
      "text": "jQuery Plugins",
      "subItems": [{
        "href": "#/form-tools",
        "text": " Form Tools"
      }, {
        "isNavItem": true,
        "href": "javascript:;",
        "text": " Datatables",
        "subItems": [{
          "href": "#/datatables/managed.html",
          "text": " Managed Datatables"
        }]
      }]
    }];
  }]);
  <script type="text/ng-template" id="tree_item_renderer.html">
    <a href="{{item.href}}" ng-class="{'nav-link nav-toggle': item.subItems && item.subItems.length > 0}">
      <span class="title">{{item.text}}</span>
    </a>
    <ul ng-if="item.subItems && item.subItems.length > 0" class="sub-menu">
      <li ng-repeat="item in item.subItems" ng-class="{'start': item.isStart, 'nav-item': item.isNavItem}" ng-include="'tree_item_renderer.html'"></li>
    </ul>
  </script>

  <div ng-app="myApp" ng-controller="TreeController">
    <ul class="page-sidebar-menu" data-keep-expanded="false" data-auto-scroll="true" data-slide-speed="200" ng-class="{'page-sidebar-menu-closed': settings.layout.pageSidebarClosed}">
      <li ng-repeat="item in menuItems" ng-class="{'start': item.isStart, 'nav-item': item.isNavItem}" ng-include="'tree_item_renderer.html'"></li>
    </ul>
  </div>
.directive('menuItem', function($compile){
    return {
        restrict: 'A',
        scope: {
            menuItem: '=menuItem'
        },
        templateUrl: 'menuItem.html',
        replace: true,
        link: function(scope, element){
            var watcher = scope.$watch('menuItem.subItems', function(){
                if(scope.menuItem.subItems && scope.menuItem.subItems.length){
                    var subMenuItems = angular.element('<ul><li ng-repeat="subItem in menuItem.subItems" menu-item="subItem"></li></ul>')
                    $compile(subMenuItems)(scope);
                    element.append(subMenuItems);
                    watcher();
                }
            });
        }           
    }
})
<li>    
    <a ng-href="{{ menuItem.href }}">{{ menuItem.text }}</a>
</li>
<script type="text/ng-template" id="categoryTree">
    {{ category.title }}
    <ul ng-if="category.categories">
        <li ng-repeat="category in category.categories" ng-include="'categoryTree'">           
        </li>
    </ul>
</script>
<ul>
    <li ng-repeat="category in categories" ng-include="'categoryTree'"></li>
</ul>