Is there a way to use ng-hide or ng-if (i.e. inside the element, not the controller) to hide the #navbar-nav ul if it has no li or visible li?
Perhaps this can be extended to hide the toggle button as well since there is nothing to show.
Currently if there are no list items, then you can still toggle (slide up and down) the navbar, and it does not look nice.
Most of the other questions I saw had to do with ng-repeat
<div class="navbar navbar-inverse navbar-fixed-top" role="navigation">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<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="#">Brand</a>
</div>
<div class="collapse navbar-collapse">
<ul class="nav navbar-nav" id="navbar-nav">
<li class="active hidden-xs">
<a href="#">Home</a>
</li>
<li class="hidden-xs">
<a href="#products">Products</a>
</li>
<li class="hidden-xs">
<a href="#overview">Overview</a>
</li>
</ul>
</div>
<!--/.nav-collapse -->
</div>
There are a few things we need to touch on here. The first is that the entire reason you use angular is to do data binding to manipulate/populate the view. With that being said you need to have something for ng-if
/ng-show
/ng-hide
to check against. And this is where the controller comes in. The controller has to contain information so that the view can be manipulated. So in this case we will want to create a controller that has a variable to contain the menu list items:
app.controller('navCtrl', function(){
this.menuItems = [
{ name: 'Home', href: '' },
{ name: 'Products', href: '' },
{ name: 'Overview', href: '' }
];
});
Now that this is done we need to bind it to the nav:
<div ng-controller="navCtrl as nav" class="navbar navbar-inverse navbar-fixed-top" role="navigation"> .... </div>
Next the nav li
items will need to have an ng-repeat
on them so that you can populate the ul
<ul class="nav navbar-nav">
<li ng-repeat="navItem in nav.menuItems">
<a ng-href="{{ navItem.href }}">{{ navItem.name }}</a>
</li>
</ul>
Now you can start doing what you are asking. Simply add a ng-if
that check if there are nav items:
<ul class="nav navbar-nav" ng-if="nav.menuItems.length > 0"> ... </ul>
You can also do this on the toggle menu:
<button ng-if="nav.menuItems.length > 0" type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"> ... </button>
So now if the controllers menuItems
is an empty array this.menuItems = []
the ul
and the button
will not be created.
Which leads me to point #2. The only way that this makes sense is if you are populating the menu items through a service
or and API call of some sort, or if you can dynamically create/delete nav items. If you are hard coding the array in the controller and not manipulating it then you know that the values will be present and there is no reason for this.
My final point in this implementation is to remove the class="hidden-xs"
from the li
as per this implementation the nav items will not show up even if they are present when the viewport is xs
.
Here is a fiddle to check out the full implementation: http://jsfiddle.net/9shaakw9/2/
Hope this helps!