2015年4月19日 星期日

Hybrid Apps開發系列之3.4:單頁面App製作(貨幣轉換器)

單頁面apps是最簡單的ionic apps形式。最簡單的版面由<ion-header-bar>與<ion-content>組成。前者是標題列;後者則是內容,下圖是版面示意圖。
圖1. 單頁面版面
換句話說,在index.html的<ion-header-bar>內輸入的內容,便會成為標題的一部分,如下列的
<h1>元素。而在<ion-content>內輸入的內容,則出現在app的主要頁面區域。
    <ion-header-bar>
        <h1 class="title">空白專案</h1>
    </ion-header-bar>
    <ion-content>
        首頁內容
    </ion-content>
接下來,本文將以匯率換算的範例說明單頁面App的製作,其介面綜合了本系列3.1~3.3的技巧,詳如下圖所示。

圖2.匯率換算介面
匯率換算app選擇「持有幣」以及「換算錢幣」、並輸入持有幣金額數額後,點選換算,便會顯示換算結果。此頁面涉及幾個部分:
  1. 介面:介面包含2個下拉選單(select)、一個按鈕(button)、以及兩個文字欄位(text input),此部份除了Ionic CSS設定之外,還必須搭配Ionic JavaScript API,以及AngularJS API。相關範例可參考:Hybrid Apps開發系列之3.1:下拉選單Hybrid Apps開發系列之3.2:輸入欄位 (Text Input)、以及Hybrid Apps開發系列之3.3:按鈕 (Buttons)
  2. 版面  (layout):版面包含三個橫行(row),每一行分別為2或3列(column),此部份透過Ionic CSS設定即可。

版面編排  (layout)

在版面編排方面,透過row, col兩個基本CSS class,加上其他特定用途的class,Ionic提供了非常方便的grid system。以圖2介面為例,基本框架如下:
  1. <ion-header-bar></ion-header-bar>
  2. <ion-content>
  3. <div class="row">
  4. <div class="col">1.1</div>
  5. <div class="col">1.2</div>
  6. </div>
  7. <div class="row">
  8. <div class="col col-33 col-offset-33">
  9. <button class="button">換算</button>
  10. </div>
  11. </div>
  12. <div class="row">
  13. <div class="col">3.1</div>
  14. <div class="col">3.2</div>
  15. </div>
  16. </ion-content>

  • 第3-6:第一行,內含兩列
  • 第7-10:第二行,只含一列。col-33代表寬度為33.3%,col-offset-33代表位置偏移33.3%

JS Bin顯示結果如下:

Ionic grid system其他更詳盡的介紹,可參考官網文件

匯率換算範例說明

index.html檔程式碼如下:
  1. <body ng-app="starter" ng-controller="exchangerCtrl" ng-init="money = 0; result = 0">
  2. <ion-header-bar class="bar-positive">
  3. <h1 class="title">匯率換算</h1>
  4. </ion-header-bar>
  5. <ion-content>
  6. <div class="row">
  7. <div class="col">
  8. <label class="item item-input item-select">
  9. <span class="input-label">
  10. 持有幣
  11. </span>
  12. <select ng-change="changeHold(holdOption)" 
  13. ng-model="holdOption" 
  14. ng-options="item.name+item.base for item in rates">
  15. </select>
  16. </label>
  17. </div>
  18. <div class="col">
  19. <label class="item item-input item-select">
  20. <span class="input-label">
  21. 換算錢幣
  22. </span>
  23. <select ng-change="changeTarget(exchangeOption)"
  24. ng-model="exchangeOption"
  25. ng-options="item.name+item.base for item in rates">
  26. </select>
  27. </label>
  28. </div>
  29. </div>
  30. <div class="row">
  31. <div class="col col-33 col-offset-33">
  32. <button class="button button-block ion-ios-home-outline" 
  33. ng-click="compute(money)"> 換算
  34. </button>
  35. </div>
  36. </div>
  37. <div class="row">
  38. <div class="col">
  39. <label class="item item-input">
  40. <input ng-model="money" type="number" />
  41. </label>
  42. </div>
  43. <div class="col">
  44. <label class="item item-input">
  45. <input ng-model="result" ng-readonly="true" type="number" />
  46. </label>
  47. </div>
  48. </div>
  49. </ion-content>
  50. </body>

  • 第2-4行:以<ion-header-bar>設定標題列。
  • 第5-49行:以<ion-content>設定內容。內容運用前述Ionic grid system提供的CSS設定版面。
  • 第8-16:下拉選單「持有幣」(可參考Hybrid Apps開發系列之3.1:下拉選單)。第12行ng-change設定下拉選單狀態改變的事件處理函式為changeHold()。第13行綁定下拉選單的項目變數為holdOption,一旦選取狀態改變,holdOption便會記錄更新後的項目值。第14行ng-options指定下拉選單的項目文字為item.name+item.base,而因未設定項目值,故會項目值從0開始遞增。rates是app.js內定義於此區塊controller之資料模型變數。
  • 第19-27行:下拉選單「換算錢幣」(可參考Hybrid Apps開發系列之3.1:下拉選單)。第23行ng-change設定下拉選單狀態改變的事件處理函式為changeTarget()。第24行綁定下拉選單的項目變數為exchangeOption,一旦選取狀態改變,exchangeOption便會記錄更新後的項目值。第25行ng-options指定下拉選單的項目文字為item.name+item.base,而因未設定項目值,故會項目值從0開始遞增。rates是app.js內定義於此區塊controller之資料模型變數。
  • 第32-33行:換算按鈕(可參考Hybrid Apps開發系列之3.3:按鈕 (Buttons))。ng-click定義事件處理函式為compute(money)。money為第40行的輸入資料,已綁定為資料模型變數。
  • 第39-41行:持有幣輸入欄位(可參考Hybrid Apps開發系列之3.2:輸入欄位 (Text Input))。ng-model綁定資料變數money。
  • 第44-46行:結果顯示欄位(可參考Hybrid Apps開發系列之3.2:輸入欄位 (Text Input))。ng-model綁定資料變數result,ng-readonly則可用來設定欄位為「唯讀」,不得修改。

搭配頁面的程式檔app.js如下:
  1. angular.module('starter', ['ionic'])
  2. .run(function ($ionicPlatform) {
  3. $ionicPlatform.ready(function () {
  4. if (window.cordova && window.cordova.plugins.Keyboard) {
  5. cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
  6. }
  7. if (window.StatusBar) {
  8. StatusBar.styleDefault();
  9. }
  10. });
  11. })
  12. .controller('exchangerCtrl', function ($scope) {
  13. $scope.rates = rates;
  14. $scope.holdOption = rates[0];
  15. $scope.exchangeOption = rates[0];
  16. $scope.compute = function (money) {
  17. $scope.money = money;
  18. $scope.result = $scope.money*$scope.holdOption.rates[$scope.exchangeOption.base];
  19. }
  20. $scope.changeTarget = function (item) {
  21. $scope.exchangeOption = item
  22. }
  23. $scope.changeHold = function (item) {
  24. $scope.holdOption = item;
  25. }
  26. })
  27. var rates = [
  28. {base: "EUR", name: "歐元", rates: {"EUR": "1.00000000", "HKD": "8.35709734",
  29. "JPY": "128.32296234", "TWD": "33.55496198", "USD": "1.07814038", }},
  30. {base: "HKD", name: "港幣", rates: {"EUR": "0.11966741", "HKD": "1.00000000",
  31. "JPY": "15.35022944", "TWD": "4.01517142", "USD": "0.12900979", }},
  32. {base: "JPY", name: "日圓", rates: {"EUR": "0.00779284", "HKD": "0.06512550",
  33. "JPY": "1.00000000", "TWD": "0.26148837", "USD": "0.00840177", }},
  34. {base: "TWD", name: "新台幣", rates: {"EUR": "0.02980185", "HKD": "0.24905698",
  35. "JPY": "3.82426189", "TWD": "1.00000000", "USD": "0.03213058", }},
  36. {base: "USD", name: "美元", rates: {"EUR": "0.92752300", "HKD": "7.75140000",
  37. "JPY": "119.02249900", "TWD": "31.12299900", "USD": "1.00000000", }}
  38. ]

  • 第12-26行:定義controller:"exchangerCtrl",處理index.html檔ng-controller指定的區塊內容。
  • 第13-15行:設定幾個資料模型變數。$scope.rates供下拉選單使用,陣列內容則定義於第28-39行。
  • 第16-19行:匯率換算計算函式,index.html已設定為按鈕點選的事件處理函式。
  • 第20-22行:下拉選單「換算錢幣」選項改變的事件處理函式。參數item是由頁面傳送過來的最新選定項目值。
  • 第23-25行:下拉選單「持有幣」選項改變的事件處理函式。參數item是由頁面傳送過來的最新選定項目值。

沒有留言:

張貼留言