かずきのBlog@hatena

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

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になるだけなので、画面イメージは省略します。