AngularJS : 1.6.5
Bootstrap : 3.3.7
※v1.2.3のサンプルはこちら。
■目次
(1)AngularJSのサービス factory、service、provider
(2)AngularJSの$qサービスでpromises/deferredパターン
(3)AngularJSの$httpサービスの基本
(4)AngularJSの$httpサービスでPOST送信
(5)AngularJSの$qサービスを使ってhttpリクエストを複数実行
(6)AngularJSの$timeoutサービスと$intervalサービス
(7)$locationサービス
(8)$rootScopeを使ってコントローラ間でデータをやり取り
(1)AngularJSのサービス factory、service、provider
1)コントローラのみの場合
SubCtrl-A
- {{item.id}}=>{{item.msg}}
SubCtrl-B
- {{item.id}}=>{{item.msg}}
2)サービスを使ってコントローラ間でログを共有
SubCtrl-A
- {{item.id}}=>{{item.msg}}
SubCtrl-B
- {{item.id}}=>{{item.msg}}
1)コントローラのみの場合 <div ng-controller="mainCtrl"> <button ng-click="open('SubCtrl-A')">SubCtrl-A</button> <button ng-click="open('SubCtrl-B')">SubCtrl-B</button> <div ng-switch on="tab"> <div ng-switch-when="SubCtrl-A"> <div ng-controller="subCtrl"> <h3>SubCtrl-A</h3> <ul> <li ng-repeat="item in logs"> {{item.id}}=>{{item.msg}} </li> </ul> <button ng-click="add('Aのテストログメッセージ')">ログ記録</button> </div> </div> <div ng-switch-when="SubCtrl-B"> <div ng-controller="subCtrl"> <h3>SubCtrl-B</h3> <ul> <li ng-repeat="item in logs"> {{item.id}}=>{{item.msg}} </li> </ul> <button ng-click="add('Bのテストログメッセージ')">ログ記録</button> </div> </div> </div> </div> 2)サービスを使ってコントローラ間でログを共有<br /> <div ng-controller="mainCtrl"> <button ng-click="open('SubCtrl-A')">SubCtrl-A</button> <button ng-click="open('SubCtrl-B')">SubCtrl-B</button> <div ng-switch on="tab"> <div ng-switch-when="SubCtrl-A"> <div ng-controller="subCtrl1"> <h3>SubCtrl-A</h3> <ul> <li ng-repeat="item in lists()"> {{item.id}}=>{{item.msg}} </li> </ul> <button ng-click="add('Aのテストログメッセージ')">ログ記録</button> </div> </div> <div ng-switch-when="SubCtrl-B"> <div ng-controller="subCtrl1"> <h3>SubCtrl-B</h3> <ul> <li ng-repeat="item in lists()"> {{item.id}}=>{{item.msg}} </li> </ul> <button ng-click="add('Bのテストログメッセージ')">ログ記録</button> </div> </div> </div> </div>
1)コントローラのみの場合 var demoApp = angular.module('demoApp', []); demoApp.controller('mainCtrl', function($scope) { $scope.tab = 'SubCtrl-A'; $scope.open = function(tab) { $scope.tab = tab; }; }); demoApp.controller('subCtrl', function($scope) { $scope.logs = []; var logCount = 0; $scope.add = function(msg) { $scope.logs.push({ id: ++logCount, msg: msg }); }; }); 2)サービスを使ってコントローラ間でログを共有 var demoApp = angular.module('demoApp', []); demoApp.provider("LogService", function () { var logLevel = "Error"; return { debugEnabled: function(chk) { if (chk) { logLevel = "Debug"; } return logLevel; }, $get: function () { var logs = []; var logCount = 0; return { lists: function() { return logs; }, add: function(msg) { logs.push({ id: ++logCount, msg: "[" + logLevel + "]" + msg }); } } } } }); demoApp.config(function(LogServiceProvider) { LogServiceProvider.debugEnabled(true); }); demoApp.controller('mainCtrl', function($scope) { $scope.tab = 'SubCtrl-A'; $scope.open = function(tab) { $scope.tab = tab; }; }); demoApp.controller('subCtrl1', function($scope,LogService) { $scope.lists = function() { return LogService.lists(); }; $scope.add = function(msg) { LogService.add(msg); }; }); ※①factoryメソッドを使った場合 demoApp.factory('LogService', function() { var logs = []; var logCount = 0; var logLevel = "Error"; return { lists: function() { return logs; }, add: function(msg) { logs.push({ id: ++logCount, msg: "[" + logLevel + "]" + msg }); } }; }); ※②serviceメソッドを使った場合 var Logger = function () { this.logs = []; this.logCount = 0; this.lists = function() { return this.logs; }; this.add = function(msg) { this.logs.push({ id: ++this.logCount, msg: "[" + this.logLevel + "]" + msg }); }; }; var errorLogger = function () { }; errorLogger.prototype = new Logger(); errorLogger.prototype.logLevel = "Error"; angular.module('demoApp', []) .service("LogService", errorLogger)
(2)AngularJSの$qサービスでpromises/deferredパターン
{{msg}}
<button ng-click="q_get(true)">msg取得(成功)</button> <button ng-click="q_get(false)">msg取得(失敗)</button><br /> {{msg}}
var demoApp = angular.module('demoApp', []); demoApp.factory('qService', function($timeout) { var totalnum=0; return { q_get: function(deferred,tf) { var updateValue = function(){ $timeout(function(){ totalnum++; if (tf) { deferred.resolve("サービス処理成功 全回数:" + totalnum ); } else { deferred.reject("サービス処理失敗 全回数:" + totalnum ); } },3000,true,tf); } updateValue(); } } }); demoApp.controller('qCtrl', function($scope,qService,$q) { $scope.q_get = function(tf) { $scope.msg = "処理中・・・"; var deferred = $q.defer(); deferred.promise.then(function (result) { $scope.msg = result; },function (reason) { $scope.msg = reason; }) qService.q_get(deferred,tf); }; });
(3)AngularJSの$httpサービスの基本
Getリクエストでサーバー内のJSONファイルデータ取得
レスポンスステータス、ヘッダー
レスポンスデータ
№ | 名前 | 年齢 | 住所 |
---|---|---|---|
{{item.id}} | {{item.name}} | {{item.age}} | {{item.address}} |
<button ng-click="getFriends(true)">データ取得</button><br /> <button ng-click="getFriends(false)">データ取得(エラー)</button><br /> <strong>レスポンスステータス、ヘッダー</strong><br /> <textarea class="form-control" rows="5">{{getFriendsResult}}</textarea> <strong>レスポンスデータ</strong><br /> <table class="table table-striped"> <thead> <tr> <th>№</th><th>名前</th><th>年齢</th><th>住所</th> </tr> </thead> <tbody> <tr ng-repeat="item in friends" > <td>{{item.id}}</td><td>{{item.name}}</td><td>{{item.age}}</td><td>{{item.address}}</td> </tr> </tbody> </table>
var demoApp = angular.module('demoApp', []); demoApp.controller('http1Ctrl', function ($scope, $http) { var showResult = function (status, headers, config) { return "status: " + status + "\n\n" + "headers(レスポンスヘッダー): " + angular.toJson(headers(),true) + "\n\n " + "config(リクエストのconfig): " + angular.toJson(config,true); }; $scope.getFriends = function (tf) { var svrURL = (tf ? "../../wp-content/themes/wp/json/friends.json" : "invalid-url.php"); var config = {}; $http.get(svrURL, config) .then(function onSuccess(response) { $scope.getFriendsResult = showResult(response.status, response.headers, response.config); $scope.friends = response.data; }, function onError(response) { $scope.getFriendsResult = showResult(response.status, response.headers, response.config); }); }; });
[ {"id": 1, "name": "相田", "age": 20, "address": "東京都品川区"}, {"id": 2, "name": "伊藤", "age": 55, "address": "神奈川県横浜市"}, {"id": 3, "name": "上野", "age": 20, "address": "埼玉県川越市"}, {"id": 4, "name": "江藤", "age": 37, "address": "東京都世田谷区"} ]
(4)AngularJSの$httpサービスでPOST送信
送信するデータ
{{send_data}}
1)AngularJSのデフォルト(JSONフォーマット)で送信
2)ヘッダー設定と送信データ変換を行ってx-www-form-urlencoded形式で送信
<span>送信するデータ</span><br /> <span>{{send_data}}</span><br /> <strong>1)AngularJSのデフォルト(JSONフォーマット)で送信</strong><br /> <button ng-click="postCall(false)">送信</button><br /> <strong>2)ヘッダー設定と送信データ変換を行ってx-www-form-urlencoded形式で送信</strong><br /> <button ng-click="postCall(true)">送信</button><br /> <textarea class="form-control" rows="3">{{postCallResult}}</textarea>
var demoApp = angular.module('demoApp', []); demoApp.controller('transCtrl', function ($scope, $http) { var logResult = function (data, status, config) { if(angular.isObject(data)) { data = angular.toJson(data,true); } return "ステータス: " + status + "\n" + "送信データ: " + data + "\n" + "Content-Type: " + config.headers["Content-Type"] ; }; $scope.send_data ={ id: "0101", name: "鈴木" }; $scope.postCall = function (trans) { if(trans){ var config = { headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, transformRequest: function(data) { var transStr; if (data) { for (var key in data) { if (transStr) { transStr += '&' + key + '=' + data[key]; } else { transStr = key + '=' + data[key]; } } } return transStr; } }; }else{ var config = {}; } $http.post("../../wp-content/themes/wp/post_test.php", $scope.send_data, config) .then(function onSuccess(response) { $scope.postCallResult = logResult(response.data,response.status,response.config); }, function onError(response) { $scope.postCallResult = logResult(response.data,response.status,response.config); }); }; });
(5)AngularJSの$qサービスを使ってhttpリクエストを複数実行
3つのhttpリクエストをチェインして実行
- {{result1}}
3つのhttpリクエストを$q.allで実行
- {{result2}}
httpリクエストをループ処理
- {{result3}}
3つのhttpリクエストをチェインして実行<br /> <button ng-click="chain()">実行</button><br /> <ul> <li ng-repeat="result1 in results1"> <span>{{result1}}</span> </li> </ul> 3つのhttpリクエストを$q.allで実行<br /> <button ng-click="all()">実行</button><br /> <ul> <li ng-repeat="result2 in results2"> <span>{{result2}}</span> </li> </ul> httpリクエストをループ処理<br /> <button ng-click="loop()">実行</button><br /> <ul> <li ng-repeat="result3 in results3"> <span>{{result3}}</span> </li> </ul>
var demoApp = angular.module('demoApp', []); demoApp.controller('chainCtrl', function ($scope, $http, $q) { $scope.chain = function() { $scope.results1 = []; $http.get("/ng/q_chain.php?first=5").then(function onSuccess(response) { $scope.results1.push(response.data); $http.get("/ng/q_chain.php?second=1").then(function onSuccess(response) { $scope.results1.push(response.data); $http.get("/ng/q_chain.php?third=3").then(function onSuccess(response) { $scope.results1.push(response.data); }); }); }); }; $scope.all = function() { $scope.results2 = []; var first = $http.get("/ng/q_chain.php?first=5"), second = $http.get("/ng/q_chain.php?second=1"), third = $http.get("/ng/q_chain.php?third=3"); $q.all([first, second, third]).then(function(result) { angular.forEach(result, function(response) { $scope.results2.push(response.data); }); }); }; $scope.loop = function() { $scope.results3 = []; $http.get("/ng/q_chain.php?init=1") .then(function onSuccess(response) { var total = response.data.length; var https = []; for(i=0; i < total;i++) { var cur = i; var ary = [response.data[i][1]]; $scope.results3.push(ary); var url = "/ng/q_chain.php?" + response.data[i][0]; var http = $http.get(url); https.push(http); }; $q.all(https).then(function(result) { i=0; angular.forEach(result, function(response1) { $scope.results3[i].push(response1.data[0],response1.data[1],response1.data[2]); i++; }); }); }); }; });
(6)AngularJSの$timeoutサービスと$intervalサービス
現在の時刻:{{time}}
{{msg}}
<button ng-click="open('timeSubCtrl-A')">SubCtrl-A</button> <button ng-click="open('timeSubCtrl-B')">SubCtrl-B</button> <div ng-switch on="tab"> <div ng-switch-when="timeSubCtrl-A"> <div ng-controller="timeSubCtrl"> <strong>SubCtrl-A</strong><br /> <strong>$intervalのサンプルコード</strong><br /> <button ng-click="intervalRun()">実行</button><br /> <span>現在の時刻:{{time}}</span> </div> </div> <div ng-switch-when="timeSubCtrl-B"> <div ng-controller="timeSubCtrl"> <strong>SubCtrl-B</strong><br /> <strong>$timeoutのサンプルコード</strong><br /> <button ng-click="delayRun()">実行</button><br /> <span>{{msg}}</span><br /> </div> </div> </div>
var demoApp = angular.module('demoApp', []); demoApp.controller('timeMainCtrl', function($scope) { $scope.tab = 'timeSubCtrl-A'; $scope.open = function(tab) { $scope.tab = tab; }; }); demoApp.controller('timeSubCtrl', function ($scope,$timeout,$interval) { var time; $scope.delayRun = function(){ $scope.msg = "実行開始" + new Date().toLocaleTimeString() + "->"; $timeout(function(){ $scope.msg += "実行終了" + new Date().toLocaleTimeString(); },5000); } $scope.intervalRun = function(){ time = $interval(function () { $scope.time = new Date().toLocaleTimeString(); console.log($scope.time); }, 2000); } var intervalStop = function() { if (angular.isDefined(time)) { $interval.cancel(time); time = undefined; } }; $scope.$on('$destroy', function() { console.log("destroy"); intervalStop(); }); });
(7)$locationサービス
1)path、search、hash、urlの指定方法
- Path:URLのパス(Searchパラメータとhashを除いた部分)を指定
- Search:クエリパラメータ(?名前1=値1&名前2=値2)を指定
- Hash:ハッシュ"#value"を指定
- URL:Path、Search、Hashを含めて指定
URL:{{url}}
2)$anchorScrollを使ってページ内スクロール
- {{item.title}}
1)path、search、hash、urlの指定方法<br /> <div ng-controller="locationCtrl"> <ul> <li>Path:URLのパス(Searchパラメータとhashを除いた部分)を指定</li> <li>Search:クエリパラメータ(?名前1=値1&名前2=値2)を指定</li> <li>Hash:ハッシュ"#value"を指定</li> <li>URL:Path、Search、Hashを含めて指定</li> </ul> <div class="btn-group "> <button class="btn btn-primary" ng-click="setUrl('reset')">Reset</button><button class="btn btn-primary" ng-click="setUrl('path')">Path</button><button class="btn btn-primary" ng-click="setUrl('search')">Search</button><button class="btn btn-primary" ng-click="setUrl('hash')">Hash</button><button class="btn btn-primary" ng-click="setUrl('url')">URL</button> </div> <p>URL:{{url}}</p> </div> 2)$anchorScrollを使ってページ内スクロール<br /> <div ng-controller="location2Ctrl"> <input type="number" ng-model="showID" /><button class="btn btn-primary" ng-click="show(showID)">指定した記事へ</button> <ul> <li ng-repeat="item in items"> <span id={{$index+1}} ng-class="{'bg-primary': item.focus}">{{item.title}}</span> </li> </ul> <button class="btn btn-primary" ng-click="show(1)">先頭の記事へ</a> </div>
var demoApp = angular.module('demoApp', []); demoApp.controller("locationCtrl", function ($scope, $location) { $scope.$on("$locationChangeSuccess", function (event) { $scope.url = $location.url(); }); var pathID = 0; var hashID = 0; var searchID = 0; $scope.setUrl = function (component) { switch (component) { case "reset": $location.url("/#nglocation"); pathID = 0; hashID = 0; searchID = 0; break; case "path": ++pathID; $location.path("/path_A" + pathID + "/path_B" + pathID ); break; case "search": ++searchID; $location.search("search" + searchID, "value" + searchID); break; case "hash": ++hashID; $location.hash("hash" + hashID); break; case "url": ++pathID; ++searchID; ++hashID; $location.url("/path_A" + pathID + "/path_B" + pathID + "?search" + searchID + "=value" + searchID + "#hash" + hashID); break; } } }); demoApp.controller("location2Ctrl", function ($scope, $location, $anchorScroll) { $scope.items = []; for (var i = 0; i < 30; i++) { $scope.items[i] = { title: "記事 " + (i + 1), focus: false }; } $scope.show = function(id) { $location.hash(id); for (var i = 0; i < $scope.items.length; i++) { $scope.items[i].focus = false; }; $scope.items[id-1].focus = true; } });
(8)$rootScopeを使ってコントローラ間でデータをやり取り
Controller-A
{{success}}
{{info}}
{{warning}}
{{danger}}
Controller-B
{{success}}
{{info}}
{{warning}}
{{danger}}
<div class="well" ng-controller="scopeCtrl"> <h4>Controller-A</h4> <form> <label>タイプ</label> <select ng-model="type" ng-options="item for item in types"></select> <label>メッセージ</label> <input ng-model="msg"><br /> <button class="btn btn-primary" ng-click="alert(type, msg)">Send Alert</button> </form> <div ng-if="success != null"> <p class="bg-success">{{success}}</p> </div> <div ng-if="info != null"> <p class="bg-info">{{info}}</p> </div> <div ng-if="warning != null"> <p class="bg-warning">{{warning}}</p> </div> <div ng-if="danger != null"> <p class="bg-danger">{{danger}}</p> </div> </div> <div class="well" ng-controller="scopeCtrl"> <h4>Controller-B</h4> <form> <label>タイプ</label> <select ng-model="type" ng-options="item for item in types"></select> <label>メッセージ</label> <input ng-model="msg"><br /> <button class="btn btn-primary" ng-click="alert(type, msg)">Send Alert</button> </form> <div ng-if="success != null"> <p class="bg-success">{{success}}</p> </div> <div ng-if="info != null"> <p class="bg-info">{{info}}</p> </div> <div ng-if="warning != null"> <p class="bg-warning">{{warning}}</p> </div> <div ng-if="danger != null"> <p class="bg-danger">{{danger}}</p> </div> </div>
var demoApp = angular.module('demoApp', []); demoApp.controller("scopeCtrl", function ($scope, $rootScope) { $scope.types = ['success','info','warning','danger']; $scope.$on("globalAlert", function (event, args) { $scope[args.type] = args.msg; }); $scope.alert = function (type, msg) { $rootScope.$broadcast("globalAlert", { type: type, msg: msg }); } });