かずきのBlog@hatena

すきな言語は C# + XAML の組み合わせ。Azure Functions も好き。最近は Go 言語勉強中。日本マイクロソフトで働いていますが、ここに書いていることは個人的なメモなので会社の公式見解ではありません。

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のように指定します。

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