5

I'm still learning Angular and have started to create a simple website. I have routing and some logic in my view to have an active class on the menu item when the url is on that page. The problem I am starting to see is if I change the url from / to /home I have to update it in the routing and view and also the logic to see if it should be active.

I was wondering is there a better way of doing this to make it DRY?

My app.js file looks like this:

    angular.module('simpleApp', ['ngRoute'])
  .config(['$routeProvider', '$locationProvider', function ($routeProvider, $locationProvider) {
    $routeProvider
      .when('/', {
        templateUrl: 'views/home/index.html'
      })
      .when('/about', {
        templateUrl: 'views/about/index.html',
        controller: 'AboutController',
        controllerAs: 'aboutCtrl'
      })
      .when('/services', {
        templateUrl: 'views/services/index.html',
        controller: 'ServicesController',
        controllerAs: 'servicesCtrl'
      })
      .when('/contact', {
        templateUrl: 'views/contact/index.html',
        controller: 'ContactController',
        controllerAs: 'contactCtrl'
      })
      .otherwise({
        redirectTo: '/'
      });
  }]);

and partial view of my index.html looks like this:

<nav class="navbar navbar-inverse" ng-controller="NavController as navCtrl">
          <div class="container-fluid">
            <!-- Brand and toggle get grouped for better mobile display -->
            <div class="navbar-header">
              <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
                <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="/#/">SimpleApp</a>
            </div>
            <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
              <ul class="nav navbar-nav">
                <li ng-class="{ 'active': navCtrl.isActive('/')}">
                  <a href="/#/">Home</a>
                </li>
                <li ng-class="{ 'active': navCtrl.isActive('/about')}">
                  <a href="/#/about">About</a>
                </li>
                <li ng-class="{ 'active': navCtrl.isActive('/services')}">
                  <a href="/#/services">Services</a>
                </li>
                <li ng-class="{ 'active': navCtrl.isActive('/contact')}">
                  <a href="/#/contact">Contact Us</a>
                </li>
              </ul>
            </div>
          </div>
        </nav>

as you can see I call the isActive method on the nav controller but I have to always make sure that url I pass in is correct.

this is my nav controller:

    angular.module('simpleApp')
  .controller('NavController', function($scope, $location) {
    this.isActive = function (url) {
      return url === $location.path();
    };
  });
Jan
  • 5,688
  • 3
  • 27
  • 44
saunders
  • 969
  • 4
  • 14
  • 25
  • possible duplicate of [Set active tab style with AngularJS](http://stackoverflow.com/questions/12295983/set-active-tab-style-with-angularjs) – Long Nguyen Aug 20 '15 at 18:13
  • I don't think its a duplicate as the question was answered with how I've written my code already. My question is how to make it dry. All be it one of the answers is to use a custom directive so will have a look at it. so thankyou for bringing this to my attention as I didn't know what to google/search on here to make sure I wasn't duplicating anything – saunders Aug 20 '15 at 19:06
  • I was pointing at the accepted answer which is the best way to do it. Requires no extra directives or methods. You simply add a custom attribute to your route like so `.when('/', { templateUrl: 'views/home/index.html', activetab: 'home' })` and then in your html you can do this `
  • ` – Long Nguyen Aug 20 '15 at 19:35
  • I am kind of doing that at the moment but its having to change it in two places where I'm trying to only change it in one place – saunders Aug 20 '15 at 19:39
  • Ah I see, well then the directive is probably your best bet. I actually prefer the ui-router module instead of the ngRoute module for my routing. Its far more powerful and already has a built in directive to handle active tabs among many other things. Its definitely worth a look if you haven't already. – Long Nguyen Aug 20 '15 at 19:42
  • I have been told its better and it is on my list to look at. but I thought it would be good to get a hand on the ngRoute to start with and then move on – saunders Aug 20 '15 at 19:45
  • ui-router is basically ngRoute with more functionality. By learning ui-router you will also be able to work with ngRoute because the basics are the same. Up to you but it will probably save you a lot of time and headaches if you switch earlier :) – Long Nguyen Aug 20 '15 at 19:47
  • okay cool. i'll move over now and try to figure it all out. thanks :) – saunders Aug 20 '15 at 19:55
  • Rolled back because you shouldn't put the answer in your question – Jan Aug 21 '15 at 15:27