javascriptangularjsyeoman-generator-angular

Dynamic template URL with Angular 1.5 directive


I am wanting to change my navbar template on a route change.

I have come up with two solutions, but I am not 100% satisfied with either.

1) I can define an ng-include outside of my view.

angular.module('automatclubApp')
  .directive('navbar', function (PartialsPath) {
    return {
      restrict: 'E',
      controller: 'NavbarCtrl',
      controllerAs: 'navCtrl'
    };
  })
  .controller('NavbarCtrl', function(PartialsPath,  $scope, $location) {
    $scope.$on('$locationChangeSuccess', function(/* EDIT: remove params for jshint */) {
        var path = $location.path();
        //EDIT: cope with other path
        $scope.templateUrl = (path==='/') ? '../scripts/directives/partials/navbar.html' : '../scripts/directives/partials/navbar_lobby.html';
    });
  });

And then include this in my index:

<body>
    <div ng-controller='NavbarCtrl'>
      <div ng-include='templateUrl'></div>
    </div>
   <div ng-view=""></div>
</body>

2) In my views/main.html file, I can include an ng-include like this:

  <ng-include src="'../scripts/directives/partials/navbar.html'"></ng-include>

Ideally, I would love to have a directive declaration in my ng-view for a bit cleaner code. Any suggestions? It says my navbar controller is undefined when I can it in ng-view, which is why it seems solution one isn't working like I intended.


Solution

  • I have a solution I am happy with.

    Directive:

    angular.module('automatclubApp')
      .controller('NavbarCtrl', function($scope, $location) {
        // $scope.myTemplate = '<span class="custom-tpl" style="color: white"> my template </span>';
        $scope.getTemplateUrl = function() {
          var path = $location.path();
          return path ==='/' ? '../scripts/directives/partials/navbar.html' : '../scripts/directives/partials/navbar_lobby.html';
        };
      })
      .directive('navbar', function ($compile) {
        return {
          restrict: 'E',
          template: '<ng-include src="getTemplateUrl()">'
        };
      });
    

    Which can be invoked in the view like this:

    <div ng-controller='NavbarCtrl'>
      <navbar></navbar>
    </div>