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
});
}
});