AngularJS动态Navbar

时间:2016-10-30 16:10:48

标签: angularjs json twitter-bootstrap

我需要帮助构建一个包含N个元素的导航栏。

我的指令看起来像这样:

<ul  class="nav navbar-nav" ng-repeat="NavItem in navitems">
    <li>
        <a href="{{NavItem.Href}}">{{NavItem.Name}}</a>
    </li>
</ul>

Navigation.html:

<div class="navbar navbar-inverse navbar-fixed-top">
    <div class="container">
        <div class="navbar-header">
            <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>
            <a class="navbar-brand" href="#">Project name</a>
        </div>
        <div class="navbar-collapse collapse">
            <navigation></navigation>
        </div>
    </div>
</div>

布局:

angular.module('tool')
.controller('NavigationController', ['$scope', '$route', 'NavigationFactory', function ($scope, $route, NavigationFactory) {
    $scope.$route = $route;

    NavigationFactory.navigation().success(function (data) {
        let nav = JSON.parse(data);
        $scope.navitems = data.NavItems;
    });
}]);

NavigationController:

angular.module('tool')
.factory('NavigationFactory', ['$http', function ($http) {
    return {
        navigation: function () {
            return $http({ method: 'GET', url: '' });
        }
    }
}]);

最后是NavigationFactory:

{
  "NavItems": [
    {
      "SubNav": [],
      "Id": 1,
      "Name": "FileSystem",
      "ParentId": 0,
      "IsAdminItem": false,
      "Href": "/#/FileSystem"
    },
    {
      "SubNav": [],
      "Id": 2,
      "Name": "Settings",
      "ParentId": 0,
      "IsAdminItem": false,
      "Href": "/#/Settings"
    }
  ]
}

以下是将要解析的JSON:

<ul  class="nav navbar-nav" ng-repeat="NavItem in navitems">
    <li>
        <a ng-hide="NavItem.SubNav.length > 0" href="{{NavItem.Href}}">{{NavItem.Name}}</a>
        <div ng-show="NavItem.SubNav.length > 0" ng-switch>
            <div ng-switch-when="true">
                <div ng-init="navitems = NavItem.SubNav" ng-include="Navigation.html"></div>
            </div>
        </div>
    </li>
</ul>

我现在拥有的内容适用于此JSON,但如果其中一个NavItem具有SubNav值,我还希望能够动态生成下拉项。

我试图通过这样做递归地使用我的指令:

{
  "NavItems": [
    {
      "SubNav": [],
      "Id": 1,
      "Name": "FileSystem",
      "ParentId": 0,
      "IsAdminItem": false,
      "Href": "/#/FileSystem"
    },
    {
      "SubNav": [
        {
          "SubNav": [],
          "Id": 3,
          "Name": "Logout",
          "ParentId": 2,
          "IsAdminItem": false,
          "Href": "/#/Logout"
        }
      ],
      "Id": 2,
      "Name": "Settings",
      "ParentId": 0,
      "IsAdminItem": false,
      "Href": "/#/Settings"
    }
  ]
}

然而,当我尝试这样做时,我没有得到任何错误,它只是没有显示。这是带有subnav的测试JSON,它给我带来了错误:

a = [1, 2]
while b = a.pop do puts b end

如何制作它以便我能够使用nth级架构动态生成带下拉列表的导航栏,这样当我想创建更多的navitems时,我可以在数据库中创建它们而不必担心前面结束?

谢谢!

修改

最终我想要嵌套下拉列表,所以我不想在我的指令中继续添加ng-repeats。

2 个答案:

答案 0 :(得分:1)

尝试更改导航指令的模板,仅声明li标记的模板。

您甚至可以专门为此声明一个新指令,然后创建一个这样的递归模板:

menu-item.directive.html

<div ng-if="!$ctrl.item.SubNav"
     ng-click="$ctrl.collapseOnClick()">
  <a href="{{ $ctrl.item.Href }}">
    {{ $ctrl.item.Name }}
  </a>
</div>

<div ng-if="$ctrl.item.SubNav"
     class="btn-group"
     uib-dropdown
     is-open="status.isopen"
     ng-mouseover="status.isopen = true"
     ng-mouseleave="status.isopen = false">

  <a href="{{ $ctrl.item.Href }}"
     ng-disabled="disabled">
    <i class="fa fa-{{ $ctrl.item.icon }}"></i> {{ $ctrl.item.Name }} <i class="fa fa-caret-down"></i>
  </a>

  <ul class="dropdown-menu" uib-dropdown-menu role="menu">
    <menu-item ng-repeat="submenuItem in $ctrl.item.SubNav" item="submenuItem"></menu-item>
  </ul>
</div>

答案 1 :(得分:0)

感谢eliagentili让我走上了正确的轨道,不过你的答案对我来说并不完全有效,所以我稍微修改了一下。

这是新指令js:

angular.module('tool')
.directive('navigation', ['$compile', function ($compile) {
    return {
        restrict: 'E',
        replace: true,
        scope: {
            item: '='
        },
        templateUrl: '/Scripts/Directives/Navigation.html'
    }
}]);

和新指令模板:

<li ng-class="{'dropdown':item.SubNav.length > 0}">
    <a ng-if="item.SubNav.length == 0" href="{{item.Href}}">{{item.Name}}</a>
    <a ng-if="item.SubNav.length > 0" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="true">{{item.Name}} <span class="caret"></span></a>
    <ul class="dropdown-menu">
        <navigation ng-repeat="SubItem in item.SubNav" item="SubItem"></navigation>
    </ul>
</li>

和布局:

<nav class="navbar navbar-default">
    <div class="container-fluid">
        <div class="navbar-header">
            <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>
            <a class="navbar-brand" href="/#/">Project name</a>
        </div>

        <div class="navbar-collapse collapse" ng-controller="NavigationController">
            <ul class="nav navbar-nav">
                <navigation ng-repeat="SubMenuItem in navitems" item="SubMenuItem"></navigation>
            </ul>
        </div>
    </div>
</nav>

希望这有助于其他人!