なにか作る

なにかを作るブログです。

AngularJSを使ったとき、BootstrapのNavbarのactive状態をどう扱うか

AngularJS と Bootstrap を組み合わせてアプリケーションを作っているときにちょっと苦労したので、せっかくなのでブログにも残しておく。

バージョン

  • AngularJS 1.4.5
  • Bootstrap 3.3.5
  • Google Chrome 45.0.2454.101 m (64-bit)

ソースコード

Navbar 専用に独自のディレクティブを作った。

navbar-deirective.js

(function() {
  angular.module("MyApp")
    .directive("navbar", function() {
      return {
        restrict: "E",
        templateUrl: "templates/pages/navbar.html",
        controller: ['$route', function($route) {
          this.isSelected = function(page) {
            return page == $route.current.activeTab;
          };
        }],
        controllerAs: "navbar"
      };
    });
})();
  • isSelected 関数を定義し、現在表示しているタブ(ページ)であるかを判定している。
  • activeTab は後述のルーティングで定義したものを参照している。

templates/pages/navbar.html

<nav class="navbar navbar-inverse navbar-fixed-top">
  <div class="container">
    <div class="navbar-header">
      <a href="#/" class="navbar-brand">TITLE</a>
    </div>
    <div class="collapse navbar-collapse">
      <ul class="nav navbar-nav">
        <li ng-class="{active: navbar.isSelected('Home')}"><a href="#/">Home</a></li>
        <li ng-class="{active: navbar.isSelected('Music')}"><a href="#/musics">Music</a></li>
      </ul>
    </div>
  </div>
</nav>
  • 各タブのリンクで isSelected 関数を呼び出し、現在表示されているタブ(ページ)なら class 属性 active を付与している。

route.js

(function() {
  angular.module("MyApp")
    .config(function($routeProvider) {
      $routeProvider
        .when('/', {
          templateUrl: 'templates/pages/top/index.html',
          activeTab: 'Home'
        })
        .when('/musics', {
          templateUrl: 'templates/pages/musics/index.html',
          controller: 'MusicController',
          controllerAs: 'music',
          activeTab: 'Music'
        })
        .otherwise({
          redirectTo: '/'
        });
    });
})();
  • activeTab はルーティングで定義している AngularJS と関係ない独自の値。

参考URL

stackoverflow.com