AngularJSで共通メニューを表示するための機能です。
機能としては、リンクをクリックした時に、classを変更してカレントページをハイライトしています。
前に作成したVersionだとclassにdirectiveを設定しないといけないので、htmlとの分離がいまいちという話があったので、改訂版を作成しました。
実際に動いているのはAngularJS Sampleにあります。
AngularJSのdirectiveを使って、作っています。
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の部分です。
$scope.$on('$routeChangeSuccess', function () {
これで、locationに変更があった場合は、イベントを捕まえられます。
functionの中で行なっているので、locationから第一階層を取得して、$scope.currentPageに保持しています。
ここを見て、現在何処にいるかを判断するわけです。
<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 使っているので、それに従って書いています。
注目する部分はng-classの部分です。
<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側で設定していた値です。
$scope.currentPage = urlFlagments[1];
これで完成です。後は、呼び出すだけです。
<!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として作っいるので、独自のタグとして入っています。
<navitop></navitop>
これだけですね!
後はangularjsがこの中に、DOMを入れてくれます。
上記のサンプルはGithubに置いてます。