作者雖然比較習慣jQueryMobile 開發Hybrid App,但是隨著angular.js
的火紅,不少框架也有專門為angular.js量身打造,雖然入門的門檻較高,各位也可以參考看看ionic版的Hybrid APP,選擇適合自己喜歡的框架吧。
一、初步的網頁架構說明
ionic的路由是非常重要的部份,因為網頁的頻寬很有限,尤其是手機上的瀏覽速度更加緩慢情況下,當然就只需要把部份的網頁碼充填某個<div></div>即可,好比jQeruyMobile 的page是一樣的意思,所以<ion-nav-view></ ion-nav-view>就好比空白的<div></div>,要用到頁面再動態充填裡面即可
<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">
<script src="lib/ionic/js/ionic.bundle.js"></script>
<script src="cordova.js"></script>
<script src="js/app.js"></script>
<script src="js/controllers.js"></script>
</head>
<!—如同Angular 的ng-app來啟動angular -- >
<body ng-app="starter">
<!—如同Angular 的路由會自動把範本(home.htm,details.html帶入-- >
<ion-nav-view animation="slide-left-right"></ion-nav-view>
<!—如同實際外部產生一隻home.html,為了減少流量所以合併在同一隻程式 —>
<script id="home.html" type="text/ng-template"> </script>
<script id="details.html" type="text/ng-template"></script>
</body>
</html>
|
ionic 要如何動態充填網頁到<ion-nav-view></ ion-nav-view> ,從www/js/app.js就是幕後最大的推手,如下面所設定的範本中state就是用/url來讀取用哪個範本(templateURL)和controller,所以每個獨立頁面都需要設定一個state
很重要,很重要,很重要!
.config(function ($stateProvider,
$urlRouterProvider) {
$stateProvider
.state('home', {
url: "/home",
templateUrl: "home.html",
controller: "AppCtrl"
})
.state('details', {
url: "/details/:id", //可以傳遞參數,參數名稱可以自訂,但要加上:
templateUrl: "details.html",
controller: function ($stateParams, $scope) {
$scope.params =
$stateParams;
}
});
$urlRouterProvider.otherwise("/home");
<!— 設定預設的路徑 -- >
});
|
補充說明:ionic 有分幾種樣式tabs設定state的參數也有些不一樣,還請各位不要囫圇吞棗
二、瞭解angular的factory
相信大家早就瞭解factory和service的差異,雖然它們功能用法差不多,但它們的回傳的方式略有不同,factory
會以物件方式回傳,service會以本身this回傳,所以聰明的選擇當然是factory,因為不會有全域變數的衝突,尤其是網頁有自動壓縮的功能,自動js打包成一個檔案,這種的問題就能避免了,以下的範例透過factory達到MVC的效果,將資料獨立在Factory 函式中。
(function () {
"use
strict";
angular.module("starter.services", []).factory("sqlLiteService", ["$rootScope", "$http", function ($rootScope, $http) {
var sqlLiteService = {};
var db = window.openDatabase("Database", "1.0", "clinicDatabase", 1000);
//建立資料表
sqlLiteService.createdTable = function () {
if (db) {
sqlList.executeNonQuery(db, "CREATE
TABLE IF NOT EXISTS clinics (id INTEGER PRIMARY KEY
AUTOINCREMENT, clinicName TEXT, clinicIP TEXT, user TEXT, password
TEXT)");
}
}
//新增資料表
sqlLiteService.add = function (clinicName, clinicIP, user, password) {
var sqlValue = "INSERT INTO
clinics (clinicName,clinicIP,user,password) VALUES('" + clinicName + "'," + "'" +
clinicIP + "','" +
user + "','" +
password + "')";
sqlList.executeNonQuery(db,
sqlValue);
}
//修改資料表
sqlLiteService.edit = function (id, clinicName, clinicIP, clinicUser, clinicPassword)
{
var query = "update clinics set
clinicName='" + clinicName + "',clinicIP
= '" + clinicIP + "',user =
'" + clinicUser + "',password
='" + clinicPassword + "'
where id=?";
sqlList.executeNonQueryWithID(db, query, id);
}
//刪除資料表
sqlLiteService.delete = function (id) {
sqlList.executeNonQueryWithID(db, "delete
from clinics where id=?", id);
}
//讀取資料表
sqlLiteService.read = function (id,callback) {
//因為sqlLite 本身非同步傳遞資料,需要回傳資料,只能呼叫 callback 回傳資料
sqlList.executeSQL(db,
"select * from clinics where id=" + id, function (readData) {
callback(readData.item(0));
});
}
sqlLiteService.list = function (callback) {
var listClinics = {};
sqlList.executeSQL(db,
"select * from clinics", function (objData) {
callback(objData);
});
}
return sqlLiteService;
}]);
})();
|
補充說明: sqlList 請參考http://joyceevent.blogspot.tw/2015/09/codova-sqlite-crud.html
然後開始注入factory 到controller
中,並呼叫factory的物件,就可以開始使用sqlLiteService
, 非常特別的是ionic 透過controller轉換其他頁面時,需要呼叫$location.path(‘xxx.html’) ,Ionic 就會依據app.js找到配對的URL,並將對應的templateUrl 注入<ion-nav-view>
angular.module('starter.controllers', ['starter.services'])
.controller('AppCtrl', function ($scope, $location, sqlLiteService) {
sqlLiteService.createdTable();
//新增資料表
sqlLiteService.list(function (objData) {
$scope.playlists = [];
for (var i = 0; i < objData.length; i++)
{
$scope.playlists.push(objData.item(i));
}
});
$scope.add = function () {
$location.path("/add");
$scope.editTitle = "新增設定";
}
$scope.edit = function (path) {
$location.path(path);
$scope.editTitle = "修改設定";
}
})
|
當我們萬事具備時,就把資料呈現在我們的畫面中,此時我們的view的layout 應該事先已經準備完成,如下所示
<body ng-app="starter">
<!—Ionic 的back 鈕 -- >
<ion-nav-bar animation="nav-title-slide-ios7" class="bar-positive">
<ion-nav-back-button class="button-icon ion-arrow-left-c">
</ion-nav-back-button>
</ion-nav-bar>
<!—Ionic 的動態注入頁面 -- >
<ion-nav-view animation="slide-left-right"></ion-nav-view>
<script id="home.html" type="text/ng-template">
<ion-view view-title="XX小幫手" cache-view="false">
<!— cashe-view 每次回到home的頁面,就會重新讀取資料 —>
<ion-content>
<ion-list>
<ion-item class="item-button-right" ng-repeat="item in playlists">
<div class="item-content">
<a href="#/details/{{item.id}}">
<h2>{{item.clinicName}}</h2>
<p>{{item.clinicIP}}</p>
</a>
</div>
<div class="button" ng-click="edit('/edit/{{item.id}}')">
<a class="button button-icon icon ion-settings"></a>
</div>
</ion-item>
</ion-list>
<button class="button button-block button-calm" ng-click="add()">
新增
</button>
</ion-content>
</ion-view>
</script>
</body>
|
補充說明 : Ionic 的ng-model的宣告名稱中需要加『.』這令作者無法理解,如果宣告名稱中沒有『.』,就無法在controller中取得ng-model的值
Ionic 的ng-model的名稱宣告的範例
<ion-view view-title="{{editTitle}}">
<ion-content>
<div class="list">
<label class="item item-input item-stacked-label">
<span class="input-label">診所名稱</span>
<input type="text" ng-model="formData.clinicName" placeholder="請輸入名稱">
</label>
<label class="item item-input item-stacked-label">
<span class="input-label">診所IP</span>
<input type="text" ng-model="formData.clinicIP" placeholder="請輸入診所IP">
</label>
<label class="item item-input item-stacked-label">
<span class="input-label">帳號</span>
<input type="text" ng-model="formData.user" placeholder="請輸入帳號">
</label>
<label class="item item-input item-stacked-label">
<span class="input-label">密碼</span>
<input type="text" ng-model="formData.password" placeholder="請輸入密碼">
</label>
</div>
<button class="button
button-block button-positive" ng-click="save()">
儲存
</button>
</ion-content>
</ion-view>
|
Ionic 的controller 不論讀取或設定,都要先初始化物件,如上所示view的ng-model宣告中formData視為物件,所以要始初化formData,才能讀取或設定ng-model
.state('edit', {
url: "/edit/:id",
templateUrl: "templates/edit.html",
controller: function ($stateParams, $scope, $location, sqlLiteService) {
$scope.params =
$stateParams;
$scope.editTitle = "編輯設定";
if ($stateParams != null) {
sqlLiteService.read($stateParams.id, function (sqlRtuenObj) {
$scope.formData = {}; <!— 要先初始化 formData -- >
$scope.formData.clinicName = sqlRtuenObj.clinicName;
$scope.formData.clinicIP =
sqlRtuenObj.clinicIP;
$scope.formData.user = sqlRtuenObj.user;
$scope.formData.password = sqlRtuenObj.password;
})
}
$scope.save = function () {
sqlLiteService.edit($stateParams.id,
$scope.formData.clinicName, $scope.formData.clinicIP, $scope.formData.user,
$scope.formData.password);
$location.path("/home");
}
}
});
|
補充說明:
ionic 的框架架構
作者為了讓clinicName 從controller 設定名稱,但是無法順利取得名稱,每次要重新刷新畫面才能讀取值,結果之後要在ion-view 加上cache-view="false" 屬性,就等同我們重新刷新畫面
其次選單框架的架構,後來終於搞懂順序關係,順序如下所示
<ion-view cache-view="false">
<ion-side-menus enable-menu-with-back-views="true">
<!—放置ionic
menu 的內容 -->
<ion-side-menu-content>
<!—放置ionic menu 的抬頭bar -->
<ion-nav-bar class="bar-positive">
<!--倒回鍵-->
<ion-nav-back-button></ion-nav-back-button>
<!--menu 鍵放置在右邊-->
<ion-nav-buttons side="right">
<!—menu 的方向 由右邊往左展開-->
<button class="button button-icon button-clear ion-navicon" menu-toggle="right"></button>
</ion-nav-buttons>
</ion-nav-bar class="bar-positive">
<!--右邊 的
menu 選擇的內容範例 -->
<ion-side-menu side="right">
<ion-header-bar class="bar-positive">
<h1 class="title">選單</h1>
</ion-header-bar>
<ion-content>
<ion-list>
<ion-item menu-close ng-click="login()">
Login
</ion-item>
<ion-item menu-close href="#/app/search">
Search
</ion-item>
<ion-item menu-close href="#/app/browse">
Browse
</ion-item>
<ion-item menu-close href="#/app/playlists">
Playlists
</ion-item>
</ion-list>
</ion-content>
</ion-side-menu>
</ion-side-menus>
</ion-view
|
Ionic的動畫換頁的css 效果似乎很少,不像jQueryMobile 效果,但Ionic的維護比JQueryMobile 方便,如果以上仍有錯誤的地方,還請前輩們加以指正,感謝各位的到訪,希望這篇文章對大家有所幫助。
沒有留言:
張貼留言