かずきのBlog@hatena

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

TypeScriptとAngularJS「サービス」

サービスというものは、シングルトンで管理されるコントローラあたりから使うものみたいです。作り方はコントローラと大して変わらないけど、モジュールのserviceメソッドで登録するらしい。

ということで、サービスとスコープとコントローラを定義してみた。サービスでは、Promiseを使ってデータを返すようにしてみました。本当は非同期になるはずなんですが、今回はさくっと返すようにしてるので、Promiseにした意味はないですが…。

AngularJSのPromiseはng.IQServuce($qでインジェクションされる)で使うことができて、defer, resolve, reject, promise, thenなどおなじみのメソッドが使えます。

ということで、一連のコードは以下のようにしてみました。

// サービス
class MyService {
    constructor(private $q: ng.IQService) { }

    load(): ng.IPromise<string> {
        var d = this.$q.defer<string>();
        d.resolve("Hello world");
        return d.promise;
    }
}

// スコープ
interface MyScope extends ng.IScope {
    message: string;
    load(): void;
}

// コントローラ
class MyCtrl {
    constructor($scope: MyScope, myService: MyService) {
        $scope.message = "init";
        $scope.load = () => {
            myService.load()
                .then(r => {
                    $scope.message = r;
                });
        };
    }
}

Hello worldを表示するには仰々しい気もしますが、まぁいいでしょう。このクラスを登録します。

// モジュールに登録
var app = angular.module("myApp", []);
// MyServiceには$qをインジェクション
app.service("MyService", ["$q", MyService]);
// MyCtrlには$scopeとMyServiceをインジェクション
app.controller("MyCtrl", ["$scope", "MyService", MyCtrl]);

そして、HTML

<!DOCTYPE html>

<html lang="ja" ng-app="myApp">
<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="app.js"></script>
</head>
<body>
    <h1>TypeScript HTML App</h1>

    <div id="content" ng-controller="MyCtrl">
        <span>{{message}}</span>
        <hr />
        <button ng-click="load()">Load</button>
    </div>
</body>
</html>

ボタンをおすと{{message}}のところがHello worldになるだけなので、画面イメージは省略します。