Ionic雖以Angular做為流程運作的基礎,然而,在頁面瀏覽 (navigation) 機制方面,卻非直接採用Angular Router模組的運作方式,而是使用「堆疊」(navigation stack)的概念。
如圖,堆疊最上方的頁面元件是目前可視頁面。當要瀏覽其他頁面元件時,則使用push(),將該元件堆到堆疊上方即可(例如上圖的push(Page3))。相反的,回到前一頁,則使用pop()(如圖左,pop()後,回到Page2)。
Ionic頁面元件瀏覽係透過 NavController元件達成。因此各頁面都有import NavController元件,並在constructor中定義相關參數,以便進行push/pop等操作:
...import { NavController } from 'ionic-angular'; ... export class HomePage { constructor(public navCtrl: NavController) { }
1. 範例:Two-Page Navigation
ionic g page指令可用來建立新頁面。在建立blank專案後,另外新增一個新頁面,便可用來示範瀏覽兩個頁面的情況。
不過,由於ionic 3支援lazy loading,新建頁面時,可以選擇該頁面是否要採用lazy loading(亦即瀏覽到該頁面,再做真正載入的動作);因此,新建頁面便有「是否採用」lazy loading的兩種情況。下列範例在首頁建立兩個按鈕,點選按鈕後分別對應到「採用」與「不採用」lazy loading的新頁面。
圖:關於我們(AppModule)按鈕不採用lazy loading |
ionic start navApp blank接著以ionic g page分別建立新頁面元件about與credit,其中建立about時額外加上--no-module參數,credit頁面則不加參數:
cd navApp ionic g page about --no-module ionic g page credit如下圖兩個頁面元件生成的檔案數量並不相同,credit元件多了一個module.ts檔:
圖:credit元件自成一個模組,--no-module參數使得about必須加入原有的AppModule |
--no-module參數使得about元件生成時,不會產生module.ts檔。然而,因所有元件都必須屬於某個模組,因此接下來必須先將about加入專案預設模組AppModule中,如此才能在專案中使用about元件。另一方面,credit元件因有生成module.ts檔,已自屬一個模組,故只須小幅修改將credit元件export出來,便可於專案中使用該元件。至於,自動生成module.ts檔是為了能讓credit元件支援lazy loading(亦即使用到該元件才載入,而非專案一開始執行即載入)。
1.1 將about元件加入AppModule
由於about元件沒有模組,因此必須修改app.module.ts將之加入AppModule之中。
# app.module.ts ... import { AboutPage } from '../pages/about/about'; @NgModule({ declarations: [ MyApp, HomePage, AboutPage ], imports: [ BrowserModule, IonicModule.forRoot(MyApp) ], bootstrap: [IonicApp], entryComponents: [ MyApp, HomePage, AboutPage ],
- 第3行:如入import設定,AboutPage為about.ts檔內建立的類別名稱。
- 第9行:在@ngModule的declareations屬性內加入AboutPage元件。
- 第19行:在@ngModule的entryComponents屬性內加入AboutPage元件。
如此一來about元件便屬於AppModule模組,而可以用於其他元件之中,例如在HomePage元件裡,以push(AboutPage)加入瀏覽堆疊,完成頁面切換瀏覽的動作。
1.2 export credit類別
至於credit元件因有自己的模組檔案credit.module.ts,然因產生的模組檔並未將元件類別CreditPage設定於exports屬性內,故需自行加入,如第12-14行:(ionic CLI版本為3.19.1,測試時間為2018/3)
import { NgModule } from '@angular/core'; import { IonicPageModule } from 'ionic-angular'; import { CreditPage } from './credit'; @NgModule({ declarations: [ CreditPage, ], imports: [ IonicPageModule.forChild(CreditPage), ], exports: [ CreditPage ] }) export class CreditPageModule {}
- 第2,10行:IonicPageModule用來封裝需要lazy loading的頁面元件,因此將模組內的CreditPage元件做為IonicPageModule.forChild()的參數。
- 第3行:credit.ts定義之元件名稱。
- 第12-14行:新增加之程式碼,將模組封裝之元件名稱export出去,才能在AppModule使用之。
另外,定義在credit.ts檔案的CreditPage元件類別,必須加上decorator指令@IonicPage(),才能成為lazy loading元件。credit.ts檔案內容如下:
設定好兩個新的元件頁面後,接著修改HomePage頁面(pages/home/home.html),加入兩個按鈕,當按下按鈕時,將分別前往AboutPage頁面元件,以及CreditPage頁面元件:import { Component } from '@angular/core'; import { IonicPage, NavController, NavParams } from 'ionic-angular'; @IonicPage() @Component({ selector: 'page-credit', templateUrl: 'credit.html', }) export class CreditPage { constructor(public navCtrl: NavController, public navParams: NavParams) { } ionViewDidLoad() { console.log('ionViewDidLoad CreditPage'); } }1.3 完成首頁:HomePage
<ion-header> <ion-navbar> <ion-title text-center> Demo:頁面瀏覽 </ion-title> </ion-navbar> </ion-header> <ion-content padding> <button ion-button block outline (click)="NavToAboutOfAppModule()"> 關於我們(AppModule) </button> <button ion-button block outline (click)="NavToCreditOfAnotherModule()"> Credit(Lazy loading) </button> </ion-content>
- <ion-header>, <ion-content> 再加上<ion-footer>是頁面的最上層元素,此處使用ion-header, ion-content佈局。ion-header是表頭部份,ion-content則是主要內容區塊。
- <ion-header>內含<ion-navbar>,此元素會頁面瀏覽過程中會自動產生「返回按鈕」。而其內則可含標題<ion-title>。
- 第10行:ion-button是ionic擴充之按鈕指令(directive)。此指令有許多屬性可改變按鈕之外觀,例如此處 block outline等,詳細說明可參考官網Ionic API DOCS關於ion-button directive之段落。
- 第10行:(click)是ionic-angular之事件繫結機制,將click事件綁定至NavToAboutOfAppModule()。
搭配home.html之home.ts檔案則必須定義兩個方法:NavToAboutOfAppModule()與NavToCreditOfAnotherModule(),在其內完成「瀏覽堆疊」之push()呼叫,如此才能切換至新增的兩個頁面元件。home.ts檔案如下
import { Component } from '@angular/core'; import { NavController } from 'ionic-angular'; import { AboutPage } from '../about/about'; import { CreditPage } from '../credit/credit'; @Component({ selector: 'page-home', templateUrl: 'home.html' }) export class HomePage { constructor(public navCtrl: NavController) { } NavToAboutOfAppModule(){ this.navCtrl.push(AboutPage); } NavToCreditOfAnotherModule(){ this.navCtrl.push('CreditPage'); } }
- 第16行:this.navCtrl為NavController物件,可用來改變瀏覽堆疊,如切換至新頁面的push(),返回前頁面pop()、以及設定堆疊首頁的setRoot()。此處設定切換至新頁面AboutPage。注意push(AboutPage)參數未加引號。
- 第19行:同樣使用push()切換至新頁面,但因其為lazy loading模組元件,故呼叫push時,使用的參數是加了引號的'CreditPage'。或者在credit.ts的@IonicPage()加入name屬性設定,也可改用name屬性值,例如:
#credit.ts檔內 ... @IonicPage({ name: 'page-credit' }) .... #home.ts檔內 ... NavToCreditOfAnotherModule(){ this.navCtrl.push('page-credit'); } ...
最後ionic serve執行時,若開啟「開發人員工具」檢視程式載入情形,便會發現只有載入about與home兩個頁面,credit因lazy loading之故,一開始並未載入,如下圖所示:
沒有留言:
張貼留言