![]() |
圖1.各種資料來源可透過factory進行管理 |
Factory基本格式
Ionic/AngularJS模組都可建立factory,做為資料層,基本格式如下:angular.module('starter',['ionic]) .factory('serviceName',function(){ return {} } )
從語法上看,Factory是一回傳物件的函式。建好factory之後,在controllers中可用"serviceName"存取factory的資料與功能。底下factory範例是一個攝氏華式度數轉換的service:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
angular.module('starter.services',[]) | |
.factory('TempService',function(){ | |
var times = 1.8; | |
var base = 32; | |
return { | |
ctof: function(degree){ | |
return degree*times+base; | |
}, | |
ftoc: function(degree) { | |
return (degree-base)/times; | |
} | |
} | |
} | |
) |
重構天氣app線上版
此次範例以天氣概況頁面為基礎,改用下拉選單在單一頁面模式下運作:index.html檔案內如下:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="utf-8"> | |
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width"> | |
<title></title> | |
<link href="lib/ionic/css/ionic.css" rel="stylesheet"> | |
<link href="css/style.css" rel="stylesheet"> | |
<!-- IF using Sass (run gulp sass first), then uncomment below and remove the CSS includes above | |
<link href="css/ionic.app.css" rel="stylesheet"> | |
--> | |
<!-- ionic/angularjs js --> | |
<script src="lib/ionic/js/ionic.bundle.js"></script> | |
<!-- cordova script (this will be a 404 during development) --> | |
<script src="cordova.js"></script> | |
<!-- your app's js --> | |
<script src="js/app.js"></script> | |
<script src="js/controllers.js"></script> | |
<script src="js/services.js"></script> | |
</head> | |
<body ng-app="starter"> | |
<ion-nav-bar class="bar-positive"> | |
</ion-nav-bar> | |
<ion-view title="天氣概況" ng-controller="weatherCtrl"> | |
<ion-content> | |
<div class="list card"> | |
<div class="item"> | |
<label class="item item-input item-select"> | |
<div class="input-label"> | |
選擇城市 | |
</div> | |
<select ng-model="myCity" | |
ng-change="changeCity(myCity)" | |
ng-options="item.q as item.name for item in citys"> | |
</select> | |
</label> | |
</div> | |
<div ng-show="myCity"> | |
<div class="item"> | |
<h2>{{city[0].name}}</h2> | |
</div> | |
<div class="item item-avatar"> | |
<img src="{{img_base_url + weather.weather[0].icon + '.png'}}"> | |
<h2>{{weather.main['temp'] - 273.15| number:1}}°C / | |
{{converter.ctof(weather.main['temp'] - 273.15) | number:1}}°F</h2> | |
<h2>{{(weather.dt)*1000 | date:'yyyy-MM-dd HH:mm:ss'}}</h2> | |
</div> | |
<div class="item"> | |
<div class="row"> | |
<div class="col">濕度</div> | |
<div class="col">{{weather.main.humidity}}%</div> | |
</div> | |
<div class="row"> | |
<div class="col">風速</div> | |
<div class="col">{{weather.wind.speed}}哩/秒</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
</ion-content> | |
</ion-view> | |
</body> | |
</html> |
- 第23-24行:分別加入js/controllers.js 與 js/services.js。
- 第33-43行:加入下拉選單(亦可參考Hybrid Apps開發系列之3.1:下拉選單)。ng-model指定使用資料模型變數myCity儲存下拉選單各選項的數值(value);選項選取狀態改變,則呼叫controller端定義的事件處理器changeCity()。最後下拉選單選項文字與數值,則從citys資料模型變數而來。如參照controllers.js的內容,則會發現citys的內容則是由Factory所提供。
- 第46行:city資料模型變數內容亦是由factory提供,由於city是陣列,此處則取第一個資料呈現。詳細說明請參考controllers.js段落。
- 其餘可參考Hybrid Apps開發系列之4.4:多頁面App程式 (天氣app-非線上版)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
angular.module('starter', ['ionic','starter.controllers','starter.services']) | |
.run(function ($ionicPlatform) { | |
$ionicPlatform.ready(function () { | |
// Hide the accessory bar by default (remove this to show the accessory bar above the keyboard | |
// for form inputs) | |
if (window.cordova && window.cordova.plugins.Keyboard) { | |
cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true); | |
} | |
if (window.StatusBar) { | |
StatusBar.styleDefault(); | |
} | |
}); | |
}) |
js/services.js檔案如下:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
angular.module('starter.services', []) | |
.factory('TempService', function ($http, $filter) { | |
var times = 1.8; | |
var base = 32; | |
var citys = [ | |
{name: "台北", q: "Taipei", on: true}, | |
{name: "台中", q: "Taichung", on: true}, | |
{name: "台南", q: "Tainan", on: true}, | |
{name: "高雄", q: "Kaohsiung", on: true}, | |
{name: "花蓮", q: "Hualian", on: true}, | |
] | |
return { | |
ctof: function (degree) { | |
return degree * times + base; | |
}, | |
ftoc: function (degree) { | |
return (degree - base) / times; | |
}, | |
get: function (city) { | |
return $http.get('http://api.openweathermap.org/data/2.5/weather', | |
{params: {'q': city}}); | |
}, | |
getCitys: function () { | |
return citys; | |
}, | |
getCityQ: function (index) { | |
return citys[index].q; | |
}, | |
getCityName: function (q) { | |
return citys.filter(function (e) { | |
return (e.q === q) | |
}) | |
} | |
} | |
} | |
) |
- 第2行:建立TempService服務。$http提供連線取得資料功能,$filter則用於陣列搜尋
- 第5-11行:陣列資料放在service端,透過後續定義的函式,便可供controller取用。
- 第13-18行:分別建立兩個服務函式ctof 與ftoc。
- 第19-22行:取得特定城市的天氣資料,city參數便是傳遞進來的城市名稱。對照controllers.js便知城市名稱是由下拉選單改變選擇項目時傳送過來的。
- 第23-25行:建立資料模型變數citys,其值就是第5-11行宣告的陣列。
- 第26-28行:提供取得城市英文名稱的服務功能。
- 第29-32行:提供取得城市中文名稱的服務功能。此處使用了陣列的.filter(),該函式可過濾出符合條件的陣列元素,此處是搜尋陣列元素中欄位q與傳送進來資料相符的元素。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
angular.module('starter.controllers', []) | |
.controller('weatherCtrl', function ($scope, $http, TempService) { | |
$scope.citys = TempService.getCitys(); | |
$scope.img_base_url = image_base_url; | |
$scope.converter = TempService; | |
$scope.changeCity = function(item){ | |
TempService.get(item) | |
.then(function (resp) { | |
$scope.weather = resp.data; | |
}, function (err) { | |
alert(err); | |
}); | |
$scope.city=TempService.getCityName(item); | |
} | |
}) | |
var image_base_url = "http://openweathermap.org/img/w/"; // open weather api icon |
- 第2行:由於使用到網路連線與自訂服務TempService兩個服務,所以必須inject此兩個模組。
- 第3,5行:使用自訂服務TempService,取得程式資料,以及讓頁面可以使用TempService。
- 第6-14行:呼叫TempService的get(item)功能,取得特定城市的天氣概況。
沒有留言:
張貼留言