先日にはてブのホットエントリになってたこの記事(Promises: ブラウザーJavaScriptの新しい非同期標準になるか?)をみるに、APIアクセスの場合は promises を使わないと、APIの応答が遅い場合に結果が取得できないし、またAPIの結果が返ってくるまでユーザを待たせてしまうことになります。
というわけで、AngularJS でAPIの結果を非同期で取得して画面を更新する、というデモを作ってみました(応答が遅いAPIを模するために、1秒のウェイトを擬似的にいれてます)。
デモはこちら⇒http://hkusu.github.io/AngularJS_apicall_demo3
下記にソースの説明をします。
※ 私のJavaScriptの経験はまだ浅いので、おかしなところがあったら教えてください^^;
① ソースツリーのWEB公開領域に、適当にJSONファイルを用意
[
{
"id": "1",
"name": "山田"
},
{
"id": "2",
"name": "鈴木"
},
{
"id": "3",
"name": "高橋"
}
]
② JSONファイルにアクセスするFactoryを用意
擬似的に1秒間ウェイトしてから、結果を返すようにしています。
angular.module('apiTestApp')
.factory('JsonData', function ($http) {
return {
getSampleData: function () {
return $http.get('data/sample.json')
.success(function(data, status, headers, config) {
// 擬似的に、1秒間ウェイト
var time = new Date().getTime();
while (new Date().getTime() < time + 1000);
return data;
});
}
}
})
;
③ Controllerから先程のFactoryを呼び出し
.then
で先程のAPIアクセスの応答があった後に、画面にAPIの応答結果を表示するようにします。
AngularJSの場合、リアルタイムのデータバイングが働くので、簡単に書けますね^^
応答を待つ間に、後続に書いた処理(今回だと $scope.show_loading = true;
の行)が実行されます。
今回は応答を待つ間は画面に「読み込み中」と表示することにします。
angular.module('apiTestApp')
.controller('MainCtrl', ['$scope', 'JsonData', function ($scope, JsonData) {
// こっちの書き方はNGパターン
//$scope.items = JsonData.getSampleData().data;
JsonData.getSampleData().then(function(res){
$scope.items = res.data;
$scope.show_loading = false; // ローディング中、を非表示へ
}
);
$scope.show_loading = true; // ローディング中、を表示
}])
;
④ ViewでHTMLへ表示
<div ng-controller="MainCtrl">
この間の部分が非同期での読み込み<br>
↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓<br>
<div ng-show="show_loading">
読み込み中..
</div>
<li ng-repeat="item in items">
{{item.id}} - {{item.name}}
</li>
↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓<br>
</div>
⑤ 結果はこんな感じ
デモはこちら⇒http://hkusu.github.io/AngularJS_apicall_demo3
ほか
- 今回のソースはGitHubに置いてあります。
- 参考:前回までの投稿(いま考えると、APIの応答が遅い場合は結果が取得できずあまり良くない..)