Dynamicly added dropdown menu in AngularJS + Bootstrap
Solution 1
Solved!
I've finally made it with ng-if
and ng-repeat-start
. With help in comments, I've found that ng-class
does not run directives.
<ul class="navbar-nav nav navbar-left">
<span ng-repeat-start="menu_element in globalMenu"></span>
<li ng-if="menu_element.dropdown !== undefined">
<a ng-href="{{menu_element.href}}" class="dropdown-toggle">
{{menu_element.label}}
<b class="caret" ></b>
</a>
<ul class="dropdown-menu">
<li ng-repeat="sub_element in $parent.menu_element.dropdown">
<a ng-href="{{sub_element.href}}">{{sub_element.label}}</a>
</li>
</ul>
</li>
<li ng-if="menu_element.dropdown === undefined">
<a ng-href="{{menu_element.href}}">
{{menu_element.label}}
</a>
</li>
<span ng-repeat-end></span>
</ul>
Working example on Plnkr. Something happened with the css on Plunker, yesterday it was working... but still it works.
Solution 2
Nice, this helped me along the way. I've a slight variation on your theme.
<ul class="nav navbar-nav">
<li ng-repeat='link in menu track by $index' ng-class='[{dropdown:link.sub}]'>
/* normal menu */
<a ng-if='!link.sub' ng-bind='link.id' ng-click='jump(link.to)'></a>
/* dropdown menu */
<a ng-if='link.sub' class="dropdown-toggle" data-toggle="dropdown">
<span ng-bind='link.id'></span>
<ul class="dropdown-menu inverse-dropdown">
/* and repeat for the submenu */
<li ng-repeat='slink in link.menu track by $index'>
<a ng-bind='slink.id' ng-click='jump(slink.to)'></a>
</li>
</ul>
</a>
</li>
</ul>
My menu array is a list of
{id:'name', to:n}
where n points to an array listing some html I push into the page. When there is a sub menu the menu array element is
{id:'name', sub:true, menu:[{id:'name', to:n}, etc.]}
I tried ui-bootstrap but never got my head around it.
MichalMazurek
Updated on June 07, 2022Comments
-
MichalMazurek almost 2 years
I'm writing a module that will create a dynamic menu on the fly. How to run a directive after adding new
<li>
with css classdropdown
which is also added by ng-class.
The code:angular.module('myapp', ['ui.bootstrap']) .factory("menuService", ["$rootScope", function($rootScope) { "use strict"; return { menu: function() { $rootScope.globalMenu; }, setMenu: function(menu) { $rootScope.globalMenu = menu; } }; }]) .controller("MainController", ["$scope", "menuService", function($scope, menuService){ menuService.setMenu([{href:"#", label:"Dropdown", dropdown:[{href:"/edit", label:"Edit"}]}, {href:'/', label:'test'}]); $scope.bodyText = "Some text"; }]);
This is the code in html
<ul class="navbar-nav nav navbar-left"> <li ng-repeat="menu_element in globalMenu" ng-class="{dropdown: menu_element.dropdown != undefined}"> <a ng-href="{{menu_element.href}}" ng-class="{'dropdown-toggle': menu_element.dropdown != undefined}"> {{menu_element.label}} <b class="caret" ng-if="menu_element.dropdown != undefined"></b> </a> <ul ng-if="menu_element.dropdown != undefined" class="dropdown-menu"> <li ng-repeat="sub_element in $parent.menu_element.dropdown"> <a ng-href="{{sub_element.href}}">{{sub_element.label}}</a> </li> </ul> </li> </ul>
Link to plunker: http://plnkr.co/edit/pgH35mmsjLJqV4yJuSYq?p=preview
So what I want to do is the same or similar as for jQuery, there I would run
$("li.dropdown").dropdown()
after adding whole ul>li blocks. I'm new to Angular and I want to make this in the angular way.I read about directives, how to use them. But I couldn't find how to apply directive in runtime. I've read about
transclude: element
in a directive (ui.bootstrap.dropdownToggle) doesn't have it enabled. I'm sure that there is a easy way, but couldn't find it myself...