AngularJSで共通メニューを作る 改訂版

AngularJSで共通メニューを表示するための機能です。
機能としては、リンクをクリックした時に、classを変更してカレントページをハイライトしています。

前に作成した[Version](http://qiita.com/sinmetal/items/6a47a67353e23f27db67 "Version")だとclassにdirectiveを設定しないといけないので、htmlとの分離がいまいちという話があったので、改訂版を作成しました。

実際に動いているのは[AngularJS Sample](http://angularjs-sample-sinmetal.appspot.com/ "AngularJS Sample")にあります。

AngularJSのdirectiveを使って、作っています。

```js:main.js
app.directive('navitop', function () {
    return {
        priority: 0,
        templateUrl: '/html/common/topmenu.html',
        replace: false,
        transclude: false,
        restrict: 'E',
        scope: false,
        controller: ['$scope', '$route', '$location', function ($scope, $route, $location) {
            $scope.$on('$routeChangeSuccess', function () {
                var urlFlagments = $location.$$path.split("/");
                $scope.currentPage = urlFlagments[1];
            });
        }]
    };
});
```

navitopという名前のdirectiveを作成しました。
キモは$routeChangeSuccessの部分です。

```js:main.js
$scope.$on('$routeChangeSuccess', function () {
```

これで、locationに変更があった場合は、イベントを捕まえられます。
functionの中で行なっているので、locationから第一階層を取得して、$scope.currentPageに保持しています。
ここを見て、現在何処にいるかを判断するわけです。

```html:topmenu.html
<div class="navbar navbar-inverse navbar-fixed-top">
  <div class="navbar-inner">
    <div class="container-fluid">
      <button type="button" class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
      </button>
      <a class="brand" href="#">AngularJS Sample</a>
      <div class="nav-collapse collapse">
        <ul class="nav">
          <li ng-class="{active:currentPage==''}"><a href="/#/">Home</a></li>
          <li ng-class="{active:currentPage=='guestbook'}"><a href="/#/guestbook/">Guestbook</a></li>
        </ul>
      </div><!--/.nav-collapse -->
    </div>
  </div>
</div>
```

これがトップメニューのhtmlです。
[twitter bootstrap](http://twitter.github.io/bootstrap/ "twitter bootstrap") 使っているので、それに従って書いています。
注目する部分はng-classの部分です。

```html:topmenu.html
<li ng-class="{active:currentPage==''}"><a href="/#/">Home</a></li>
<li ng-class="{active:currentPage=='guestbook'}"><a href="/#/guestbook/">Guestbook</a></li>
```

currentPage==''の条件が一致すれば、classにactiveが設定されます。
currentPageはdirective側で設定していた値です。

```js:main.js
 $scope.currentPage = urlFlagments[1];
```

これで完成です。後は、呼び出すだけです。

```html:index.html
<!DOCTYPE html>
<html lang="ja" ng-app="sample">
<head>
  <meta charset="utf-8">
  <title>AngularJS sample</title>
  <meta name="description" content="">
  <meta name="author" content="">
  <!-- Le HTML5 shim, for IE6-8 support of HTML elements -->
  <!--[if lt IE 9]>
  <script src="//html5shim.googlecode.com/svn/trunk/html5.js"></script>
  <![endif]--><!-- Le styles -->
  <link rel="stylesheet" href="/lib/bootstrap/css/bootstrap.min.css">
  <link rel="stylesheet" href="/lib/bootstrap/css/bootstrap-responsive.min.css">
  <style type="text/css">
    body {
      padding-top: 50px;
      padding-left: 30px;
    }
  </style>
</head>
<body>
  <navitop></navitop>
  <div ng-view></div>
</div>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<script src="//code.angularjs.org/1.0.7/angular.min.js"></script>
<script src="//code.angularjs.org/1.0.7/angular-resource.min.js"></script>
<script src="/script/main.js"></script>
</body>
</html>
```

directiveとして作っいるので、独自のタグとして入っています。

```html:index.html
<navitop></navitop>
```

これだけですね！
後はangularjsがこの中に、DOMを入れてくれます。

上記のサンプルは[Github](https://github.com/sinmetal/angularjs-sample "Github")に置いてます。