AngularJS & TypeScriptでngResouceを使ってみた。(query編)

2015.06.24

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

前回はプロジェクトのひな形作成を行いました。
今回はREST APIから一覧の取得を行います。

ひな形作成

前回の記事を参考に、AngularJS Angular-Resouceとその型定義ファイルの取得を行います。

npm init
npm install -save bower
npm install -save dtsm
bower init
bower install -save angular
bower install -save angular-resource
dtsm init
dtsm install  --save angularjs/angular.d.ts
dtsm install  --save angularjs/angular-resource.d.ts

実装

script/app.ts

///<reference path='../typings/bundle.d.ts' />
module app{
    'use strict';
    angular.module(
        'tsr',
        ['ngResource'],
        ($locationProvider) => {
            $locationProvider.html5Mode(true);
        }
    )
}

取得した型定義ファイルを参照し、ngResouceをDIするといった内容です。 $locationProviderの設定を行う箇所でアロー関数式を用いています。

script/IScore.ts

///<reference path='../typings/bundle.d.ts' />
module app.model{
    'use strict';
    export interface IScore extends ng.resource.IResource<IScore>{
        subject :string;
        score   :number;
    }
}

モデルを定義しています。 その際に、IResoucインターフェースを継承し、型パラメータとして自身を指定しています。 モデルとして扱う値をプロパティとして指定しています。(subject・score)

script/IScoreResource.ts

///<reference path='../typings/bundle.d.ts' />
///<reference path='./IScore.ts' />
module app.resource{
    'use strict';
    export interface IScoreResource extends ng.resource.IResourceClass<app.model.IScore>{
    }
}

先ほど作成したIScoreを返すResourceを作成します。
IResouceClassを継承し、 型パラメータとして先ほど作ったIScoreインターフェースを指定します。

script/qeuryService.ts

///<reference path='../typings/bundle.d.ts' />
///<reference path='./IScore.ts' />
///<reference path='./IScoreResource.ts' />
module app.service{
    'use strict';
    export class queryService{
        private $resource: ng.resource.IResourceService;

        constructor($resource: ng.resource.IResourceService) {
            this.$resource = $resource;
        }
        private resource(): app.resource.IScoreResource{
            var apiUrl = '/score.json';
            return <app.resource.IScoreResource> this.$resource(apiUrl);
        }

        public getScoreList(): ng.resource.IResourceArray<app.model.IScore>{
            return this.resource().query();
        }
    }
    angular.module('tsr').service('queryService',queryService);
}

ここが今回の肝になります。 コンストラクタで$resouceの初期化を行い、 resouce()メソッド内で取得先のURLの設定・先ほど作ったIScoreResouceへのキャストを実施しています。
取得先のURLですが、今回はの例では直接JSONファイルを指定しています。 最後に取得用のメソッドとして、getScoreList()で先ほど作ったIScoreResouce内のqueryメソッドを呼んでいます。

script/indexController.ts

///<reference path='./queryService.ts' />
module app.controller {
    'use strict';

    export class indexController {
        public scores:Array<app.model.IScore>;
        constructor(public queryService:app.service.queryService){
            this.scores = this.queryService.getScoreList();
        }
    }
    angular.module('tsr').controller('indexController',indexController);
}

Controller内では、コンストラクタでqueryServiceに対してDIを実施し、
qeuryService内のqueryメソッドでscoresプロパティに値をセットしています。

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Typescript ngResouce Sample</title>
    <script src="/bower_components/angular/angular.js"></script>
    <script src="/bower_components/angular-resource/angular-resource.js"></script>
    <script src="/script/app.js"></script>
    <script src="/script/queryService.js"></script>
    <script src="/script/indexController.js"></script>
</head>
<body ng-app="tsr">
    <div ng-controller="indexController as indexCtrl">
        <ul>
            <li ng-repeat="score in indexCtrl.scores">
                {{score.Subject}} : {{score.Score}}
            </li>
        </ul>

    </div>
</body>
</html>

描画側のViewは特別なことは特にやっていません。
コントローラー側の値をViewにBindingさせているといった流れになります。

以下に今回の作例を公開してあります。
CM-Kajiwara/ts-ng-resouceSample

最後に

typescriptでは、ngResouce関連のインターフェースの取り扱いが重要になります。 今回の作例では値を取得して表示するまでを行いましたが、
次は、値の更新や登録を行いたいと思います。

参考サイト

vvakame/angularjs-typescript
akirasosa/ts-ng-webpack