來(lái)扯點(diǎn)ionic3[2] 頁(yè)面一線牽 珍惜這段緣

往期傳送門
來(lái)扯點(diǎn)ionic3[0] 吹完牛再入門也不遲
來(lái)扯點(diǎn)ionic3[1] 創(chuàng)建一個(gè)新頁(yè)面

上一次我們完成了一個(gè)新頁(yè)面的創(chuàng)建
可能你被亂七八糟的概念搞得心煩意亂
不過(guò)你那么聰明又那么好看
我相信你肯定花了點(diǎn)時(shí)間就把他們搞懂了

我們先看看手里有幾個(gè)頁(yè)面?

  • AboutPage
  • ContactPage
  • HomePage
  • TestPage

我們要做什么?
在HomePage上放一個(gè)頁(yè)面,點(diǎn)擊之后跳轉(zhuǎn)到TestPage.

怎么做?
可謂非常簡(jiǎn)單,只需要完成三步。

1.實(shí)踐:喜歡我就點(diǎn)我啊

1.1 開(kāi)始前:復(fù)原上一節(jié)的初始狀態(tài)

  • 文件:pages/tabs/tabs.ts

上一次我們?yōu)榱擞^察新創(chuàng)建的TestPage,直愣愣把首屏的HomePage給替換掉了,我們先把他恢復(fù)原狀:

  1. 將 tab1Root 重新指向 HomePage
  2. 刪除 TestPage 的 import 語(yǔ)句
import { Component } from '@angular/core';

import { AboutPage } from '../about/about';
import { ContactPage } from '../contact/contact';
import { HomePage } from '../home/home';

@Component({
  templateUrl: 'tabs.html'
})
export class TabsPage {

  tab1Root = HomePage;
  tab2Root = AboutPage;
  tab3Root = ContactPage;

  constructor() {

  }
}

直接serve運(yùn)行本地服務(wù)器,一切又完好如初,畫(huà)面太美不敢看。

1.2 在HomePage搞一個(gè)按鈕

  • 文件: pages/home/home.html

把原來(lái) ion-content 里的內(nèi)容刪除,加入這一個(gè)這樣的按鈕

<button ion-button>喜歡我就點(diǎn)我呀</button>

沒(méi)錯(cuò)是你熟悉的那個(gè)button標(biāo)簽
ion-button 是一個(gè)內(nèi)置指令
讓按鈕在視覺(jué)上呈現(xiàn)出與操作系統(tǒng)相符的效果

iOS下按鈕的效果
不加指令的話,額…

1.3 在HomePage組件中引入TestPage

  • 文件: pages/home/home.ts
  1. 引入 TestPage
  2. 在 HomePage 類中定義 testPage 屬性;
  3. 在構(gòu)造函數(shù)中農(nóng)將 testPage 指向 TestPage,以便模板可以使用。
import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';

import { TestPage } from '../test/test';

@Component({
    selector: 'page-home',
  templateUrl: './home.html'
})
export class HomePage {

  testPage;

  constructor(public navCtrl: NavController) {
    this.testPage=TestPage;
  }

}

1.4 頁(yè)面一線牽

  • 文件:pages/home/home.html
  • 為button加上 [navPush] 指令
<button ion-button [navPush]="testPage">喜歡我就點(diǎn)我呀</button>

這時(shí)我們切換到瀏覽器,點(diǎn)擊Home頁(yè)面上的按鈕,發(fā)現(xiàn)頁(yè)面流暢地切換到了Test上去了。

2.在業(yè)務(wù)邏輯中實(shí)現(xiàn)跳轉(zhuǎn)

剛才,我們通過(guò)了 [navPush] 指令,讓模板中的按鈕“超鏈接”到了一個(gè)新頁(yè)面。但是在更復(fù)雜的場(chǎng)景中,這樣簡(jiǎn)單的鏈接可能不能符合我們的需求。比如我們需要在用戶點(diǎn)擊按鈕時(shí),進(jìn)行一些業(yè)務(wù)處理,再跳轉(zhuǎn)到下一個(gè)頁(yè)面,這時(shí)候就可以利用NavController中的push方法來(lái)實(shí)現(xiàn),同樣也只有三步:

2.1 引入 NavController

ionic把a(bǔ)pp的眾多交互封裝成了若干個(gè)controller,其中NavController就是用來(lái)管理和導(dǎo)航頁(yè)面的一個(gè)controller。由于幾乎每一個(gè)頁(yè)面都會(huì)用到NavController,我們發(fā)現(xiàn)在HomePage中已經(jīng)有了引入語(yǔ)句了。

import { NavController } from 'ionic-angular';

此外,類的構(gòu)造函數(shù)定義了一個(gè)NavController類型的參數(shù),以告訴angular在創(chuàng)建頁(yè)面時(shí),需要傳入(注入)一個(gè)NavController的實(shí)例.

constructor(public navCtrl: NavController){
}

2.2 使用push方法來(lái)進(jìn)行跳轉(zhuǎn)

在類中編寫(xiě)一個(gè)方法,我們就叫它pushTestPage吧,調(diào)用navCtrl對(duì)象的push方法,將頁(yè)面導(dǎo)航到TestPage上

pushTestPage(){
    this.navCtrl.push(TestPage);
  }

此時(shí)文件 home.ts 的完整代碼

import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';

import { TestPage } from '../test/test';

@Component({
    selector: 'page-home',
  templateUrl: './home.html'
})
export class HomePage {
  
  constructor(public navCtrl: NavController) {
  }

  pushTestPage(){
    this.navCtrl.push(TestPage);
  }

}

2.3 將方法綁定到按鈕點(diǎn)擊事件

在home.html中,為button元素綁定click事件

<button ion-button (click)="pushTestPage()">喜歡我就點(diǎn)我呀</button>

為什么不是 onclick="pushTestPage()" 因?yàn)?pushTestPage 不是一個(gè)全局函數(shù),它是 TestPage 組件中的一個(gè)方法,經(jīng)過(guò)封裝之后早已對(duì)外不可見(jiàn),不過(guò)可以通過(guò)使用(click) 指令來(lái)直接調(diào)用組件內(nèi)的方法。

這樣我們就可以在pushTestPage里添加更加復(fù)雜的業(yè)務(wù)邏輯,以滿足我們的需求。

3.將參數(shù)傳遞給下一個(gè)頁(yè)面

有時(shí)我們完成了一個(gè)頁(yè)面上的業(yè)務(wù)之后,要把相關(guān)的數(shù)據(jù)傳給下一個(gè)頁(yè)面處理,這時(shí)候就需要向被push的頁(yè)面?zhèn)魅胂嚓P(guān)的參數(shù)。NavController的push方法的第二個(gè)參數(shù)接收一個(gè)對(duì)象。

3.1 為push函數(shù)添加第二個(gè)參數(shù)

假設(shè)我們要為TestPage傳入一個(gè)標(biāo)題,用來(lái)顯示到頁(yè)面上,我們?yōu)閜ush方法傳入一個(gè)對(duì)象。

 pushTestPage(){
    this.navCtrl.push(TestPage,{
        title:'沒(méi)有人可以比我?guī)?
    });
  }

3.2 引入NavParam并使用

利用NavParams的get方法,可以將傳進(jìn)來(lái)的頁(yè)面參數(shù)讀取出來(lái)。
切換到 test.ts,完成三個(gè)步驟
1.引入NavParams并,并在構(gòu)造函數(shù)添加注入語(yǔ)句
2.為TestPage類添加title屬性,讀取參數(shù)并賦給title
3.將title輸出到模板中

  • 文件 test.ts
import { Component } from '@angular/core'

import { NavParams } from 'ionic-angular' //step1

@Component({
    selector: 'page-test',
    templateUrl:'./test.html'
})
export class TestPage {

    title:string; //step2

    constructor(public params:NavParams){ //step1
        this.title=this.params.get('title'); //step2
    }
}
  • 文件 test.html
    如果很多場(chǎng)景的模板引擎,在模板中利用雙花括號(hào) {{ }} 將組件的屬性輸出到界面上。
<ion-header>
  <ion-navbar>
    <ion-title>
      Test
    </ion-title>
  </ion-navbar>
</ion-header>
<ion-content>
  <!--[step3]-->
  <h1>{{title}}</h1>
</ion-content>

4. 老司機(jī)必會(huì):手動(dòng)返回

如同進(jìn)入頁(yè)面,我們?cè)谕顺鲰?yè)面的時(shí)候,除了用戶點(diǎn)擊返回按鈕外,也有可能在完成了業(yè)務(wù)之后,自動(dòng)返回上一個(gè)頁(yè)面,這時(shí)候可以使用NavController的pop方法來(lái)實(shí)現(xiàn)。

  • 文件 test.ts
import { Component } from '@angular/core'

//注意這里
import { NavController, NavParams } from 'ionic-angular'

@Component({
    selector: 'page-test',
    templateUrl:'./test.html'
})
export class TestPage {

    title:string;

    //注意這里
    constructor(public navCtrl:NavController,public params:NavParams){
        this.title=this.params.get('title');
    }

    //新方法
    popPage(){
        this.navCtrl.pop();
    }
}
  • 文件 test.html
    在模板中添加返回按鈕
<ion-header>
  <ion-navbar>
    <ion-title>
      Test
    </ion-title>
  </ion-navbar>
</ion-header>
<ion-content>
  <h1>{{title}}</h1>
  <button ion-button (click)="popPage()">返回</button>
</ion-content>

5. 擴(kuò)展內(nèi)容:ionic的頁(yè)面機(jī)制

過(guò)往我們?cè)诰W(wǎng)頁(yè)上進(jìn)行頁(yè)面之間的鏈接,是通過(guò)<a>標(biāo)簽來(lái)實(shí)現(xiàn)的。而我們現(xiàn)在制作的 web APP,雖然使用了前端技術(shù),但頁(yè)面的概念跟之前卻所有不同。

ionic APP在編譯過(guò)后,實(shí)際上只有一個(gè)index.html網(wǎng)頁(yè),它是一個(gè)單頁(yè)面應(yīng)用。你所看到的頁(yè)面之間的切換,實(shí)際上都是利用 js 來(lái)替換界面上的元素,并不是傳統(tǒng)意義上的網(wǎng)頁(yè)之間的跳轉(zhuǎn)。因?yàn)閭鹘y(tǒng)的網(wǎng)頁(yè)跳轉(zhuǎn),是需要向服務(wù)器發(fā)送請(qǐng)求并下載資源的,即便再快的網(wǎng)速都會(huì)有一定的響應(yīng)時(shí)間。這在瀏覽器上非常正常,但如果是在手機(jī)APP上,這樣的響應(yīng)時(shí)間會(huì)嚴(yán)重影響操作的流暢性。而單頁(yè)面已經(jīng)加載了基礎(chǔ)的資源,在操作過(guò)程中,只需要替換部分的內(nèi)容,請(qǐng)求部分的資源,配合一些交互設(shè)計(jì),讓操作沒(méi)有卡頓感。所以在移動(dòng)web盛行的今天,單頁(yè)面應(yīng)用也是一種大勢(shì)所趨。

ionic APP中的頁(yè)面實(shí)質(zhì)上是一個(gè)棧的結(jié)構(gòu)(實(shí)際上多數(shù)原生應(yīng)用也是這樣的),但從當(dāng)前頁(yè)面上引入一個(gè)新頁(yè)面時(shí),瀏覽器(或操作系統(tǒng))會(huì)加載新頁(yè)面的資源,然后把它添加到棧頂。在界面上的表現(xiàn)就是,新頁(yè)面“遮住了”原有的頁(yè)面,下層頁(yè)面的內(nèi)容和資源依舊在內(nèi)存中。

而上層頁(yè)面被pop掉的時(shí)候,上層頁(yè)面彈出棧,相應(yīng)的內(nèi)存被釋放(在圖中棧頂由C變成了B),在視覺(jué)表現(xiàn)上就是上面的頁(yè)面被“移開(kāi)”了,下層的頁(yè)面“暴露了出來(lái)”。

所以APP中的頁(yè)面是有層級(jí)關(guān)系的,用戶在首頁(yè)一層一層地進(jìn)入了新頁(yè)面(A->B->C),回到首頁(yè)時(shí)就得一層一層退出來(lái)(C->B->A),所以我們?cè)谠O(shè)計(jì)頁(yè)面的時(shí)候,腦海中有明確這樣的層級(jí)關(guān)系,如果棧的層次過(guò)多了(超過(guò)了5層),就會(huì)給用戶體驗(yàn)帶來(lái)困擾。

最后提一下TabsPage,TabsPage可以被理解層一個(gè)特殊的頁(yè)面,這個(gè)頁(yè)面中又包含了若干個(gè)頁(yè)面棧(Tab),每個(gè)頁(yè)面棧相互獨(dú)立,通過(guò)Tab按鈕來(lái)相互切換。一個(gè)頁(yè)面棧中的push和pop不會(huì)影響到其它棧的表現(xiàn),也就是當(dāng)你在不同的tab中切換時(shí),看到的響應(yīng)的棧頂頁(yè)面。

下一章:來(lái)扯點(diǎn)ionic3[3] 頁(yè)面的生命周期事件,也就是凡間所說(shuō)的鉤子

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容