かずきのBlog@hatena

日本マイクロソフトに勤めています。XAML + C#の組み合わせをメインに、たまにASP.NETやJavaなどの.NET系以外のことも書いています。掲載内容は個人の見解であり、所属する企業を代表するものではありません。

TypeScriptとAngularJS「ページ切り替え」

Single Page Applicationだとしても、疑似的にページ切り替えしますよね。ということで、そのための機能がAngularJSにもあります。

使い方

angular-route.js(min.js)をangular.js(min.js)の後に追加。angular.moduleのモジュール作成時に"ngRoute"への依存関係を追加する。スクリプトの追加は置いといて、モジュール作成時の依存関係の追加は以下のようなコードになります。

// AngularJSのモジュール定義
var navApp = angular.module("navApp", ["ngRoute"]);

こうすることで、navApp.configメソッドに$routeProviderを受け取ってルートの構成を行うことが出来るようになります。

$routeProviderのwhenメソッドを使ってURLごとに、どのコントローラを、どのテンプレートで表示するか設定できます(他にも色々設定できるけどここでは省略)

// ルートの定義
navApp.config(["$routeProvider", ($routeProvider: ng.route.IRouteProvider) => {
    $routeProvider
        // #/hello へはhello.htmlをテンプレートにしてHelloCtrlをコントローラとして適用したものを表示
        .when("/hello", {
            controller: "HelloCtrl",
            templateUrl: "views/hello.html"
        })
        // #/world へはworld.htmlをテンプレートにしてWorldCtrlをコントローラとして適用したものを表示
        .when("/world", {
            controller: "WorldCtrl",
            templateUrl: "views/world.html"
        });
}]);

どれにもマッチしないときにどうするかというogherwiseというメソッドも用意されています。

コントローラ・スコープの作成

コントローラとスコープは通常通り作ればOKです。

// hello.htmlのスコープとコントローラ定義
interface HelloScope extends ng.IScope {
    message: string;
}
navApp.controller("HelloCtrl", ["$scope", ($scope: HelloScope) => {
    $scope.message = "Hello at " + Date();
}]);


// world.htmlのスコープとコントローラ定義
interface WorldScope extends ng.IScope {
    message: string;
}
navApp.controller("WorldCtrl", ["$scope", ($scope: WorldScope) => {
    $scope.message = "World at " + Date();
}]);

テンプレートは、部分的なHTMLになります。簡単にスコープのmessageプロパティを表示するだけのテンプレートはこんな感じになります。

views/hello.html

<h3>Hello page</h3>
{{message}}

views/world.html

<h3>World page</h3>
{{message}}

ページの作成

コントローラとページのテンプレートができたので、それを流し込むためのページを作ります。ng-viewというディレクティブをつけたところが、テンプレートが流し込まれるところになります。

<!DOCTYPE html>

<html lang="ja" ng-app="navApp">
<head>
    <meta charset="utf-8" />
    <title>TypeScript HTML App</title>
    <link rel="stylesheet" href="app.css" type="text/css" />
    <script src="Scripts/angular.min.js"></script>
    <script src="Scripts/angular-route.min.js"></script>
    <script src="app.js"></script>
</head>
<body>
    <h1>Sample navigation app</h1>
    <ul>
        <li><a href="#/hello">Hello page</a></li>
        <li><a href="#/world">World page</a></li>
    </ul>
    <div id="content" ng-view></div>
</body>
</html>

URLは、#/helloや#/worldのように指定します。

実行してリンクをクリックすると、画面遷移するけどページは、リロードされてない素敵なページが表示されます。ふむ。