jsonで一括取得ではなく、その都度検索したい、って場合の処理。
ベース
ui-routerでjsonを取得したリスト画面
[monaca]ui-routerでjson取得処理。
angular-animateの導入
詳細は、[monaca]ui-routerで詳細スワイプ処理参照。
animate.cssの導入
同上
html
index.html
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<meta http-equiv="Content-Security-Policy" content="default-src * data: gap: https://ssl.gstatic.com; style-src * 'unsafe-inline'; script-src * 'unsafe-inline' 'unsafe-eval'">
<script src="components/loader.js"></script>
<script src="script.js"></script>
<link rel="stylesheet" href="components/loader.css">
<link rel="stylesheet" href="css/style.css">
</head>
<body ng-app="MyApp">
<ons-page>
<!-- ツールバー -->
<ons-toolbar>
<div class="center">JSON検索</div>
</ons-toolbar>
<!-- 画面のメイン部分 -->
<div>
<ons-button ui-sref="search">JSON検索</ons-button>
</div>
<!-- 遷移読込部分 -->
<div style="padding: 20px 10px;" ui-view></div>
<!-- ローディング読込用ディレクティブ -->
<my-loader></my-loader>
</ons-page>
<!-- リスト画面 -->
<ons-template id="search.html">
<div ng-controller="SearchController">
<!-- 入力欄 -->
<ons-input ng-model="searchText" modifier="underbar" placeholder="国名等" float></ons-input>
<!-- 検索ボタン -->
<ons-button ng-click="searchCountry();">検索</ons-button>
<div>{{message}}</div>
<!--検索結果 -->
<dl ng-repeat="(i, item) in list">
<!-- 国名をタップしたら、詳細表示有無を反転させる -->
<dt ng-click="shown[i] = !shown[i];">
<!-- 詳細未表示時は右向きアイコン -->
<ons-icon icon="fa-chevron-circle-right" ng-show="!shown[i]"></ons-icon>
<!-- 詳細表示時は右向きアイコン -->
<ons-icon icon="fa-chevron-circle-down" ng-show="shown[i]"></ons-icon>
{{item.country}}
</dt>
<!-- 詳細情報は、詳細表示ON/OFFの切り替えでCSSを設定し、アニメーション表示する -->
<dd ng-show="shown[i]">
<ul>
<li>英語名:{{item.english}}</li>
<li>数: {{item.number}}</li>
<li>三字: {{item.three}}</li>
<li>二字: {{item.two}}</li>
<li>場所: {{item.place}}</li>
<li>各行政区分: {{item.division}}</li>
</ul>
</dd>
</dl>
</div>
</ons-template>
<!-- ローディング画面 -->
<ons-template id="loader.html">
<div ng-if="$root.isLoading" class="loader-parent"><div class="loader">Loading...</div></div>
</ons-template>
</body>
</html>
json
country.json
{
"list": [
{
"country": "アイスランド",
"division": "ISO 3166-2:IS",
"english": "Iceland",
"number": "352",
"place": "北ヨーロッパ",
"three": "ISL",
"two": "IS"
},
{
"country": "アイルランド",
"division": "ISO 3166-2:IE",
"english": "Ireland",
"number": "372",
"place": "西ヨーロッパ",
"three": "IRL",
"two": "IE"
},
(略)
]
}
javascript
script.js
var myApp = angular.module('MyApp', ['onsen', 'ui.router', 'ngAnimate']);
// 遷移処理
myApp.config(['$stateProvider', '$urlRouterProvider', function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('search', {
url: '/search',
templateUrl: 'search.html'
})
}]);
// 検索画面用コントローラ
myApp.controller('SearchController', ['$scope', '$state', '$rootScope', 'JsonCountryService', function($scope, $state, $rootScope, JsonCountryService) {
$scope.searchCountry = function() {
// まず、ローディングを回す
$rootScope.isLoading = true;
// Jsonデータ取得
JsonCountryService.run($scope.searchText).then(
function(resultList) {
// 結果リストが取れたら、スコープに設定
$scope.message = resultList.length + "件見つかりました。";
$scope.list = resultList;
// ローディング終了
$rootScope.isLoading = false;
}, function(response) {
$scope.message = "検索結果がありませんでした。";
$scope.list = null;
// ローディング終了
$rootScope.isLoading = false;
}
);
}
}]);
// ローディングタグ
myApp.directive('myLoader', function() {
return {
restrict : 'E',
replace: true,
templateUrl: "loader.html"
};
});
// 画面遷移タイミング処理
myApp.run(['$rootScope', '$transitions', '$state', function($rootScope, $transitions, $state){
$transitions.onSuccess({to:'*'}, function(trans){
// ページ読み込み成功
// ローディングフラグOFF
$rootScope.isLoading = false;
});
}]);
// JSON読込サービス
myApp.service('JsonCountryService', ['$q', '$timeout', '$http', '$filter', function($q, $timeout, $http, $filter){
this.run = function (searchText) {
console.log("JsonCountryService searchText="+ searchText);
var deferred = $q.defer();
$timeout(function(){
$http({
method: 'GET',
url: 'country.json'
}).then(function successCallback(response) {
// 成功した場合
console.log("JsonCountryService success");
var resultList;
if (searchText && searchText.length > 0) {
// 検索文字列が指定されている場合、リストの中から該当値のものだけ取得する
// 検索範囲は絞りこまない
// 完全一致ではなく、部分一致とする
resultList = $filter("filter")(response.data.list, searchText, false);
}
else {
// 検索文字列が指定されていない場合、全データを返す
resultList = response.data.list;
}
// 検索結果を返す
deferred.resolve(resultList);
}, function errorCallback(response) {
// 失敗した場合
var msg = "JsonCountryService json取得失敗: "+ response.status;
console.error(msg);
console.log("response.data"+ response.data);
console.log("response.headers"+ response.headers);
console.log("response.config"+ response.config);
console.log("response.statusText"+ response.statusText);
console.log("response.xhrStatus"+ response.xhrStatus);
deferred.reject(msg);
});
});
return deferred.promise;
};
}]);
css
style.css
/* --------------------- 検索結果 ------------------------------- */
dt {
font-size: large;
font-weight: bold;
}
ul {
padding: 0px;
}
/* --------------------- 詳細項目の表示/非表示アニメーション ------------------------------- */
dd.ng-hide-remove {
animation: bounceInLeft 0.5s ease 0s 1 normal;
-webkit-animation: bounceInLeft 0.5s ease 0s 1 normal;
display: block!important;
}
dd.ng-hide-add {
animation: bounceOutLeft 0.5s ease 0s 1 normal;
-webkit-animation: bounceOutLeft 0.5s ease 0s 1 normal;
display: block!important;
}
(略)
処理の流れ
-
JSON検索
ボタン押下-
state=search
に遷移
-
-
検索
ボタン押下-
searchCountry
を実行-
$rootScope.isLoading = true
でローディングを表示する - ローディングの詳細は[monaca]ui-router遷移時にローディング処理を入れてみた。参照。
-
ng-model
で$scope
にバインドされたsearchText
を取得 -
$scope.searchText
を引数に、JsonCountryService
を実行
-
-
-
JsonCountryService
内部の処理-
country.json
を取得- 取得に成功した場合
- 検索文字列が指定されている場合
$filter("filter")(response.data.list, searchText, false)
- 第一引数: 検索対象リスト
- 第二引数: 検索文字列(検索範囲を絞り込みたい場合は、
{ "country": searchText }
のように指定する - 第三引数:false: 部分一致検索, (true: 完全一致検索)
- フィルタ結果を返す
- 検索文字列が指定されていない場合
- 検索結果全件を返す
- 検索文字列が指定されている場合
- 取得に失敗した場合
- エラーメッセージを返す
- 取得に成功した場合
-
-
JsonCountryService
から結果リストが戻ってきた場合- 検索結果件数を
message
に設定 - 検索結果リストを
list
に設定 - ローディング終了
- 検索結果件数を
-
JsonCountryService
から結果リストが戻ってこなかった場合- エラーメッセージを
message
に設定 - ローディング終了
- エラーメッセージを
-
ng-repeat
で検索結果リストの内容をリスト表示する-
dd
タグは、shown[i]
がtrueの場合のみ表示する。(初期表示時、false) -
dt
タグ押下時、shown[i]
の値を反転する-
dd
タグ表示のタイミングで、dd.ng-hide-remove
スタイルクラスが実行され、bounceInLeft
アニメーションが実施される -
dd
タグ非表示のタイミングで、dd.ng-hide-add
スタイルクラスが実行され、bounceOutLeft
アニメーションが実施される - アニメーションの詳細は、[monaca]ui-routerで詳細スワイプ処理参照。
-
-
shown[i]=true
の場合、fa-chevron-circle-down
アイコンを表示する -
shown[i]=false
の場合、fa-chevron-circle-right
アイコンを表示する
-