移動應用框架 ionic2 自學須知的基本知識點

官方文件:http://ionicframework.com/docs/v2/

        Ionic(ionicframework)一款接近原生的Html5移動App開發框架。

IONIC 是目前最有潛力的一款 HTML5 手機應用開發框架。通過 SASS 構建應用程式,它提供了很多 UI 元件來幫助開發者開發強大的應用。 它使用 JavaScript MVVM 框架和AngularJS 來增強應用。提供資料的雙向繫結,使用它成為
Web 和移動開發者的共同選擇。Ionic是一個專注於用WEB開發技術,基於HTML5建立類似於手機平臺原生應用的一個開發框架。Ionic框架的目的是從web的角度開發手機應用,基於PhoneGap的編譯平臺,可以實現編譯成各個平臺的應用程式。

注意:這裡講的是ionic2的知識點,畢竟它與ionic 1.0有著較顯著的區別。

Ionic2的版本更新介紹:https://github.com/driftyco/ionic/blob/master/CHANGELOG.md

Ionic2 Iclic Labs:http://www.icliclabs.com/

Ionic2 專案參考:market.ionic.io

Ionic2的文件學習:來自 yan_xiaodi 的 Ionic2系列——Ionic
2 Guide 官方文件中文版

Ionic2 APP啟動慢? 參考: Ionic 2 speed up boot time?

Ionic2 遠端除錯:Ionic 專案除錯工具

icon和splash的生成:Icon and Splash Screen Image Generation

ionic2的主題切換實現:User-Selected Style Themes in an Ionic 2 Application

ionic2處理安卓物理鍵返回退出應用:ionic2實戰-完美處理安卓硬體返回按鈕

Ionic3的頁面懶載入:Ionic 3 Lazy Loading

(一)Ionic
的安裝與執行

 

1、 下載安裝 node.js,可以在命令列中使用node–v命令檢視當前安裝的node.js的版本;

2、 使用 npm install ionic –g命令可以安裝Ionic,不過需要注意的是此時安裝的版本為Ionic
1.0版本。可以使用npm install [email protected]–g安裝beta版本,如可以使用npm
install[email protected] –g安裝beta.22版本;

2017-02-17 現在直接npm install ionic -g即可安裝到 Ionic2

3、 安裝Ionic
後,可以使用 ionic start ionicdemo –v2初始化一個空專案,預設採用tabs template作為初始化專案的模板,如果需要其他的模板,那麼在專案名稱後面新增上對應的模板名稱即可,如:ionic
start ionicdemo tutorial –v2;(–v2引數明確了使用2.0版本去初始化專案)

4、 使用 ionic serve可以執行Ionic專案;

5、 使用 ionic platform add android或ionic platform add ios命令可以新增兩個手機平臺的部署檔案(使用ionicplatform
list 命令可以檢視當前的平臺資訊);

6、 在專案中新增了兩個平臺的部署檔案,可以通過platform資料夾下進行檢視,相應地,在Xcode匯入ios部署檔案或在Android
studio匯入Android部署檔案,可以進行相應地真機除錯;

注:

1)更新 node_modules/ionic-native 到最新的命令:

npm i --save [email protected]

or

cnpm i --save [email protected]

有時可能遇到 ionic-native中外掛不能使用的問題,可能是由於當前專案中ionic-native版本過低,我們需要將其更新到最新版本。需要注意:更新到最新版本後,可能出現其他問題哦~

2)檢視ionic-native版本:

npm list ionic-native

or

cnpm list ionic-native

3)在ionic start專案時,可能出現如下錯誤:

Error with start undefined

Error Initializing app: There was an error with the spawned command: npminstall

There was an error with the spawned command: npminstall

Caught exception:

undefined

解決方案:

After this error, run npm install , if get some error related to git , than follow below steps, it resolved for me:
Go to https://git-for-windows.github.io/ and install git
than open git cmd
run below command: 
git config –global url.”https://”.insteadOf git://

(二)Ionic頁面的生命週期

// 頁面被載入完成後呼叫的函式,切換頁面時並不會進行重新載入,因為有cache的存在
onPageLoaded() {
console.log('page 1: page loaded.');
}
// 頁面即將進入的時候
onPageWillEnter() {
// 在這裡可以做頁面初始化的一些事情
console.log('page 1: page will enter.');
}
// 頁面已經進入的時候
onPageDidEnter() {
console.log('page 1: page did enter.');
}
// 頁面即將離開的時候
onPageWillLeave() {
console.log('page 1: page will leave.');
}
// 頁面已經離開的時候
onPageDidLeave() {
console.log('page 1: page did leave.');
}
// 從 DOM 中移除的時候執行的生命週期
onPageWillUnload() {
}
// 從 DOM 中移除執行完成的時候
onPageDidUnload() {
}

(三)Ionic元件

1、Tab控制元件

圖示:http://ionicframework.com/docs/v2/ionicons/ 

tabs.html

<ion-tabs>
<ion-tab [root]="tab1Root" tabTitle="Home" tabIcon="home"></ion-tab>
<ion-tab [root]="tab2Root" tabTitle="About" tabIcon="information-circle"></ion-tab>
<ion-tab [root]="tab3Root" tabTitle="Contact" tabIcon="contacts"></ion-tab>
</ion-tabs>

<ion-tabs>
<ion-tab [root]="tab1Root" tabTitle="Home" tabIcon="home"></ion-tab>
<ion-tab [root]="tab2Root" tabTitle="About" tabIcon="information-circle"></ion-tab>
<ion-tab [root]="tab3Root" tabTitle="Contact" tabIcon="contacts" tabBadge="3"></ion-tab>
</ion-tabs>

<ion-tabs>
<ion-tab [root]="tab1Root" tabTitle="Home" tabIcon="home"></ion-tab>
<ion-tab [root]="tab2Root" tabTitle="About" tabIcon="information-circle"></ion-tab>
<ion-tab [root]="tab3Root" tabTitle="Contact" tabIcon="contacts" tabBadge="3" tabBadgeStyle="danger"></ion-tab>
</ion-tabs>

預設首先進入第三個tab頁面:

Html控制

<ion-tabs selectedIndex="2">
<ion-tab [root]="tab1Root" tabTitle="Home" tabIcon="home"></ion-tab>
<ion-tab [root]="tab2Root" tabTitle="About" tabIcon="information-circle"></ion-tab>
<ion-tab [root]="tab3Root" tabTitle="Contact" tabIcon="contacts" tabBadge="3" tabBadgeStyle="danger"></ion-tab>
</ion-tabs>

JS控制

<ion-tabs #mainTabs>
<ion-tab [root]="tab1Root" tabTitle="Home" tabIcon="home"></ion-tab>
<ion-tab [root]="tab2Root" tabTitle="About" tabIcon="information-circle" tabBadge="3" tabBadgeStyle="danger"></ion-tab>
<ion-tab [root]="tab3Root" tabTitle="使用者中心" tabIcon="person"></ion-tab>
</ion-tabs>

import {Component} from '@angular/core';
import {HomePage} from '../home/home';
import {AboutPage} from '../about/about';
import {ContactPage} from '../contact/contact';
import {Tabs} from 'ionic-angular';
import {Injectable, ViewChild} from '@angular/core';
@Component({
templateUrl: 'build/pages/tabs/tabs.html'
})
export class TabsPage {
@ViewChild('mainTabs') tabRef: Tabs;
private tab1Root: any;
private tab2Root: any;
private tab3Root: any;
constructor() {
// this tells the tabs component which Pages
// should be each tab's root Page
this.tab1Root = HomePage;
this.tab2Root = AboutPage;
this.tab3Root = ContactPage;
}
ionViewDidEnter() {
this.tabRef.select(2);
}
}

2、Button控制元件

<button>Basic Button</button>
<button gray>Gray Button</button>
<button danger>Danger Button</button>
<button outline>Outline Button</button>
<button clear>Clear Button</button>
<button round>Round Button</button>
<button block>Block Button</button>
<button small>Small Button</button>
<button large>Large Button</button>
<button>
<ion-icon name="home"></ion-icon>
Button
</button>
<button>
Button
<ion-icon name="home"></ion-icon>
</button>
<button>
<ion-icon name="home"></ion-icon>
</button>

3、Input控制元件

<ion-list>
<ion-item>
<ion-label floating>使用者名稱</ion-label>
<ion-input type="text" value="" [(ngModel)]="user.username"></ion-input>
</ion-item>
<ion-item>
<ion-label stacked>密碼</ion-label>
<ion-input type="password" value="" [(ngModel)]="user.password"></ion-input>
</ion-item>
</ion-list>
<button block (click)="showFill()">登入</button>

export class ContactPage {
public user = {
username: 'parry',
password: ''
};
constructor(private navCtrl: NavController) {
}
showFill() {
alert(this.user.username);
console.log(this.user.password);
}
}

4、Loading控制元件、Alert控制元件

import {Component} from '@angular/core';
import {NavController, LoadingController, AlertController} from 'ionic-angular';
@Component({
templateUrl: 'build/pages/contact/contact.html'
})
export class ContactPage {
public user = {
username: 'parry',
password: ''
};
constructor(private navCtrl: NavController,
private loadingCtrl: LoadingController,
private alertCtrl: AlertController) {
this.navCtrl = navCtrl;
}
showFill() {
alert(this.user.username);
console.log(this.user.password);
}
login() {
/*// 建立 loading 視窗,模擬3秒後登入成功, loading 視窗消失
let loading = Loading.create({
content: '正在登入...',
duration: 3000, //單位是毫秒
});
this.navCtrl.present(loading);
// 真實的邏輯應該是:去請求登入的 API,返回結果後,進行loading視窗的隱藏
setTimeout(() => {
loading.dismiss();
}, 3000);*/
if(this.user.username == '' || this.user.username.length <= 3) {
// alert 提醒使用者注意使用者名稱的正確性
let alertUserNameError = this.alertCtrl.create({
title: '使用者中心',
subTitle: '輸入的使用者名稱格式不正確!',
buttons: ['OK']
});
alertUserNameError.present();
} else {
let loading = this.loadingCtrl.create({
content: 'Please wait...',
spinner: 'dots',
duration: 3000, //單位是毫秒
});
loading.present();
setTimeout(() => {
loading.dismiss();
}, 3000);
}
}
}

5、Toast控制元件

// 2. 使用 Toast 控制元件
let toast = this.toastCtrl.create({
message: '輸入的使用者名稱格式不正確!',
duration: 3000,
});
toast.present();

6、Grid佈局

<ion-row>
<ion-col>
<div class="textAlignRight marginTop10"><button clear>還沒有賬號?點選註冊</button></div>
</ion-col>
</ion-row>

7、 modal控制元件

// 匯入註冊頁面
import {Register} from '../contact/register';

// 開啟註冊頁面
openRegisterPage() {
let modal = this.modalCtrl.create(Register);
modal.present();
}

import {Component} from '@angular/core';
@Component({
templateUrl: 'build/pages/contact/register.html'
})
export class Register {
}

8、 Toolbar控制元件

<ion-toolbar>
<ion-title>使用者註冊</ion-title>
<ion-buttons end>
<button (click)="dismiss()">
<span showWhen="ios">取消</span>
<ion-icon name="md-close" showWhen="android,windows"></ion-icon>
</button>
</ion-buttons>
</ion-toolbar>

修改:

<ion-header>
<ion-toolbar>
<ion-title>使用者註冊</ion-title>
<ion-buttons end>
<button (click)="dismiss()">
<span showWhen="ios">取消</span>
<ion-icon name="md-close" showWhen="android,windows"></ion-icon>
</button>
</ion-buttons>
</ion-toolbar>
</ion-header>
<ion-content padding>
<h5>Parameters passed:</h5>
</ion-content>

9、 List控制元件

<ion-list>
<ion-item>
<ion-avatar item-left><img src="../images/1.jpg" alt="頭像"></ion-avatar>
<h2>哈哈</h2>
<p>(ˇˍˇ) 想~</p>
</ion-item>
<ion-item>
<ion-avatar item-left><img src="../images/2.jpg" alt="頭像"></ion-avatar>
<h2>美女</h2>
<p>(ˇˍˇ) 想~</p>
</ion-item>
</ion-list>

繫結資料來源:

資料來源的宣告

// 一般資料來源都是從 api 進行獲取,這裡我們只是模擬一些已經取到了資料
public contacts = [
{'contactid': 1, 'contactname': '夢小白', 'contacttext': '18888888888'},
{'contactid': 2, 'contactname': '夢小白2', 'contacttext': '18888888888'},
{'contactid': 3, 'contactname': '夢小白3', 'contacttext': '18888888888'},
{'contactid': 4, 'contactname': '夢小白4', 'contacttext': '18888888888'},
{'contactid': 5, 'contactname': '夢小白5', 'contacttext': '18888888888'},
{'contactid': 6, 'contactname': '夢小白6', 'contacttext': '18888888888'},
{'contactid': 1, 'contactname': '夢小白7', 'contacttext': '18888888888'},
{'contactid': 2, 'contactname': '夢小白8', 'contacttext': '18888888888'},
{'contactid': 3, 'contactname': '夢小白9', 'contacttext': '18888888888'},
{'contactid': 4, 'contactname': '夢小白10', 'contacttext': '18888888888'},
{'contactid': 5, 'contactname': '夢小白11', 'contacttext': '18888888888'},
{'contactid': 6, 'contactname': '夢小白12', 'contacttext': '18888888888'},
];

<ion-list>
<ion-item *ngFor="#contact of contacts" (click)="itemClick($event, contact)">
<ion-avatar item-left><img src="../images/{{contact.contactid}}.jpg" alt="頭像"></ion-avatar>
<h2>{{contact.contactname}}</h2>
<p>{{contact.contacttext}}</p>
</ion-item>
</ion-list>

10、卡片佈局

<ion-card>
<ion-item>
<ion-avatar item-left>
<img src="../images/6.jpg" alt="頭像">
</ion-avatar>
<h2>Elon Musk</h2>
<p>來自 iPhone 6s</p>
</ion-item>
<img src="../images/c1.jpg" alt="圖片">
<ion-card-content>
<p>我又釋出了一輛新車,上天入地捨我其誰?呵呵</p>
</ion-card-content>
<ion-item>
<button primary clear item-left><ion-icon name="thumbs-up"></ion-icon><div>888 贊</div></button>
<button primary clear item-left><ion-icon name="text"></ion-icon><div>600 評論</div></button>
<ion-note item-right>
1小時前
</ion-note>
</ion-item>
</ion-card>

11、navigation控制元件

itemClick(event, contact) {
//console.log(event);
//console.dirxml(contact);
//alert(contact.contactname);
this.navCtrl.push(ContactDetails, {item: contact});
}

ContactDetails頁面

/**
* Created by Administrator on 2016/8/23 0023.
*/
import {Component} from '@angular/core';
import {NavParams} from 'ionic-angular';
@Component({
templateUrl: 'build/pages/about/contactdetails.html'
})
export class ContactDetails {
private item = '';
constructor(public params: NavParams) {
this.item = params.data.item;
}
}

<ion-header>
<ion-navbar>
<ion-title>{{item.contactname}}</ion-title>
</ion-navbar>
</ion-header>
<ion-content padding>
{{item.contactname}} 的手機號碼為:{{item.contacttext}}
</ion-content>

(四)Cordova元件介紹

1、Image Picker元件

2、Geolocation元件

// 獲取位置資訊
Geolocation.getCurrentPosition().then((resp) => {
console.log(resp.coords.latitude);
console.log(resp.coords.longitude);
});

3、Local Notifications元件

// 本地提醒元件
LocalNotifications.schedule({
text: '本地化提醒-您啟動了Ionic App',
at: new Date(new Date().getTime()   10000),
sound: null
});

(五)專案實戰

1、快速生成App圖示和啟動頁面

MakeAppicon

Ios.hvims.com

Launcher Icon Generator

iconhandbook.co.uk/reference/chart/android

2、使用localStorage儲存狀態資訊

localStorage.setItem(key, value)

localStorage.getItem(key)

 

注:Modal頁面的關閉需要使用到ViewController中的dismiss方法。

 

3、Modal關閉後父頁面的概念和方法

 

4、Ionic中的網路請求

跨域請求問題:
http://enable-cors.org/
 (當然在App中不會出現,只會在瀏覽器除錯的過程中出現)

// 這裡是請求 API 的實現,注意跨域請求的問題,請參見 http://enable-cors.org/
this.http.get('http://xxx/account/Login?email='   this.user.username   '&password='   this.user.password)
.subscribe(data => {
let res = data.json();
if(res.LoginStatus == 1) {
localStorage.setItem('username', this.user.username);
localStorage.setItem('logined', 'true');
//自身 modal 隱藏
this.viewCtrl.dismiss(this.user.username);
loading.dismiss(); //登入進度隱藏
} else {
let toast = this.toastCtrl.create({
message: '登入失敗!',
duration: 2000,
});
toast.present();
}
}, err => {
let toast = this.toastCtrl.create({
message: '登入失敗!',
duration: 2000,
});
toast.present();
});

5、List中滑動刪除資料

<ion-list>
<ion-item-sliding *ngFor="#contact of contacts">
<ion-item (click)="itemClick($event, contact)">
<ion-avatar item-left><img src="images/{{contact.contactid}}.jpg" alt="頭像"></ion-avatar>
<h2>{{contact.contactname}}</h2>
<p>{{contact.contacttext}}</p>
</ion-item>
<ion-item-options>
<button danger (click)="removeContact(contact)">
<span padding><ion-icon name="trash"></ion-icon> 刪除</span>
</button>
</ion-item-options>
</ion-item-sliding>
</ion-list>

6、整合極光推送實現訊息推送

// 設定客戶端的別名,用於定向接收訊息的推送

window.plugins.jPushPlugin.setAlias(‘Client’  loginResult.UserId);

 

// Client(只能是單一值):單獨的一臺裝置繫結到jPush,就相當於裝置的ID號碼,server端推送的時候只能推送到ID級別的。

 

var arrayObj = new Array(‘Tags’  loginResult.UserId);

window.plugins.jPushPlugin.setTags(arrayObj);

//Tags:其實就是分組的意思,那麼這樣指定後,在使用者登入的時候 分配一個分組名給使用者,那麼推送訊息的時候,就可以推送給這個分組。 應用場景:如果使用者有多個裝置,並且這些裝置上可以同時登入app,那麼我們推送訊息應該推送給這幾個裝置。

 

//Client – 1,只是這一臺裝置收到通知。

//Tag – 1,多臺裝置都設定叫
Tag – 1。

7、iOS打包與AppStore上架

8、Android打包與釋出

參考學習:

https://babeljs.io

http://kangax.github.io/compat-table/es6/

https://github.com/driftyco

https://github.com/driftyco/ionic-preview-app/

http://www.typescriptlang.org/docs/

http://mhartington.io/post/ionic2-external-libraries/