[Ionic 2从入门到精通] 2.8 导航

如果你有Ionic 1或者Angular 1的背景,那么你以前应该处理过URL,状态等之间的路由导航。Ionic在这个上的专注点是使用一个导航栈,他引入了pushing 压入视图到navigation stack导航栈popping 弹出。在具体了解Ionic 2中是如何具体实现这个之前,我们先来了解一下这个概念。

压入与弹出

想象一下你的root page 根页面是一张画有小猫的纸,然后你将这张纸放到桌子上。那么现在他是桌子上唯一的一张纸,你现在正在从上往下盯着他。由于他目前是桌子上唯一的一张纸,所以你可以看到这个小猫图片:

1.8.1.jpg

现在,我们假设你想看另一张不同的纸(也就是去到另一个页面),那么你会将另一张纸压入到你的纸张栈上面。我们就假设这是一张小狗的图片吧,你拿出另一张纸,然后将他放到小猫上面:

1.8.2.jpg

小猫还在那里,但是我们已经看不到他了,因为他在小狗后面。我们更深入一点,假设我们压入一张小牛的图片,看起来应该是这样的:

小牛

小猫和小狗都在那里,但是小牛在最上面所以我们只看得到小牛。现在我们稍微倒过来一点。由于纸张都是按顺序的堆起来的,所以我们可以非常容易的通过弹出来回溯他们。如果你想回到小狗的图片,你可以弹出纸张栈,移除当前顶部的纸张(小牛)。如果你想回到小猫的图片,你可以再次弹出纸张栈,也就是移除当前顶部的小狗图片。现在我们回到了开始的地方。
你应该看到了这种导航方式对维护历史记录多方便,在导航到子视图的时候非常好理解,但是讲压入弹出就没那么好理解了。有时候你想直接回到某个页面而不触发这个变更。(例如,进入应用之前的登录界面,甚至是通过菜单改变的小部分区域)
在本例中,我们更改根页面,以我们桌子上的图片打比方,即忽略当前栈中的其他图片只关心桌子上当前显示的图片:

小牛

上面的例子中,我看到一个小牛的页面作为根页面,与将他显示到栈顶来比,它只有它自己。
刚开始,将页面设置为根页面来导航还是将他压入栈来进行导航很难理解。一般来讲,如果你想要转到的页面上当前页面的子页面,或者如果你想使用导航的回退功能,那么用压入的方式。举例,当我正在浏览艺术家列表,然后点击其中一个以显示详情就需要将他压入。当我浏览了大量页面表单然后点击‘下一个’进入到表单的第二页的时候,我就需要压入那个第二页了。
如果你想要转到的页面不是当前视图的子页面,或者他是应用的不同部分,这个时候你就可以使用设置根页面的方式了。例如,当你有一个在进入应用之前的登录也,在用户登录验证成功之后,你就需要该变更应用的根目录里。如果你有一个侧边菜单有DashboardShopAboutContact选项,在用户选择这些选项的时候你就可以设置相应的根页面
始终记住根页面和根组件不一样,普通来讲,根组件(在app.module.ts里定义的)定义了根页面是什么 -- 根页面在应用中到处都可以改,然后跟组件不能更改。

Ionic 2中的基本导航

好了,我们了解了原理,所以现在我们来深入一个实际的Ionic 2范例看一下压入弹出以及设置根页面以及如何在页面之间传递参数
所有这些的核心是Ionic提供的NavController。你会经常看到Ionic 2应用中导入它:

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

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

    constructor(public nav: NavController) {

    }
}

我们注入了NavController然后创建了他的应用,这样我们在类里面可以使用它。也许你猜到了,NavController帮助我们控制导航 -- 所以我们来看一下如何使用他来压入弹出
压入页面需要一个页面,将他放到导航栈的顶部(这样将会把它设置为当前页面),大概是这样的:

this.nav.push(SecondPage);

这里用到了我们之前创建的NavController引用,你只需要提供需要导航的页面的引用就可以了,当然这个页面也需要在页头导入:

import {SecondPage} from '../second-page/second-page';

同时添加到app.module.tsentryComponentsdeclarations数组里。当触发压入代码的时候,应用将会转到新的页面。当你压入一个页面的时候,导航栏(假定你有)会自动出现一个‘返回’按钮,所以通常你是不同担心通过弹出导航回之前的页面,因为‘返回’按钮自动帮你完成了这个操作。
有些情况下你需要手动弹出一个页面,你可以这样去做:

this.nav.pop();

非常简单,对不对?我之前讲过,还有其他方法来切换页面,也就是设置根页面。如果你看一眼app.ts的时候你发现下面这行代码:

rootPage: any = MyPage;

在根元件里面声明rootPage会设置根页面,因为根组件的模板是这样的:

<ion-nav [root]="rootPage"></ion-nav>

这样我们将会设置<ion-nav>的root属性为rootPage定义的值。当你在应用的任何角落想要更改根页面的时候,可以通过我们的老朋友NavController来实现 —— 你只需要调用他的setRoot方法:

this.nav.setRoot(SecondPage);

页面之前端的参数

移动应用的一个基本需求是指页面之间传递参数。一个很常见的例子是当使用‘Master Detail’模式(也就是你有一个列表的条目,在你点击其中一个条目的时候跳转到另一个页面显示选中条目详情)的时候。当你导航到详情页面的时候,我们需要知道我们要展示的条目的数据,这些数据需要从之前的页面传过来。在Ionic 2中,可以通过NavParams来实现。首先,你需要在压入(setRoot里面也可以用)调用的时候传入需要传递的数据:

this.nav.push(SecondPage, {
    thing1: data1,
    thing2: data2
});

这跟我们之前做的是一模一样的,除了增加了一个额外的参数,这个参数是一个包含了我们需要传递到SecondPage的数据的对象。然后,在接受页面,我们导入NavParams然后将它们注入到构造器:

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

@Component({
    selector: 'second-page',
    templateUrl: 'second-page.html'
})

export class SecondPage {
    constructor(nav: NavController, navParams: NavParams){

    }
}

然后你就可以通过以下方式来获取传入的参数:

this.navParams.get('thing1');

导航组件

Ionic提供的一些组件都有不一样的导航行为。这些不是核心导航概念,但是在应用中它会和导航相冲突。所以,我们来看一下他们是什么和何时使用它们。

模态框 Modals

也许你已经熟悉了模态框的理念。在网络开发中,模态框基本上是一些将所有其他内容挡住后面的弹出框。通常模态框有‘lightbox’样式,一个暗化的背景和聚焦的内容区域。
Ionic里面的模态框也是一样的,他在你的内容之上弹出,但是他看起来跟其他正常页面没有区别。通常来讲,当你想给用户一个启动然后直接移除而不是回退的视图的时候,你会用到模态框,而不是压入页面。
模态框有一个很酷的能力就是他支持者移除的时候向启动他的页面传回数据。例如,你可以创建一个这样的模态框(记得导入和注入ModalController):

let myModal = modalCtrl.create(MyPage);
myModal.present();

注意,模态框是‘呈现’的,而不是压入到导航栈。当我们想要从模态框传回一些数据的时候,我们只要在他呈现之前给他添加onDismiss处理器就可以了:

let myModal = modalCtrl.create(MyPage);

myModal.onDismiss(data => {
    console.log(data);
});

myModal.present();

这样,当模态框移除的时候,我们可以使用他回传的数据做些事情了。移除模态框的方法是在模态框内部调用以下方法:

this.view.dismiss();

此处的viewViewController的引用,他和NavController差不多也需要导入和注入到构造器。如果我们想在隐藏的时候往onDismiss里面传递数据的话,我们需要这样去操作:

let data = {
    thing1: "value1",
    thing2: "value2"
};

this.view.dismiss(data);

现在,data对象就被传到到启动模态框的页面里面的onDismiss处理器里面了。

标签页

标签页是一个非常流行的组件,对我们应用里的导航有很大的冲击。标签页的使用非常简单,在模板里面这么用就可以了:

<ion-tabs>
    <ion-tab [root]="tab1Root" tabTitle="Tab 1" tabIcon="navigate"></ion-tab>
    <ion-tab [root]="tab2Root" tabTitle="Tab 2" tabIcon="person"></ion-tab>
    <ion-tab [root]="tab3Root" tabTitle="Tab 3" tabIcon="bookmarks"></ion-tab>
</ion-tabs>

然后在类定义中定义这样去定义页面:

tab1Root: any = TabOne;
tab2Root: any = TabTwo;
tab3Root: any = TabThree;

constructor(){

}

需要记住的是每个标签页有他自己的根页面。你可以这个去想,切换标签页相当于切换不同的根页面,然后在每个标签页里压入和弹出页面。在标签页布局中,可以在每个页签之前切换,每个页签维护了他自己的历史记录。

侧边菜单

侧边菜单实际上做的跟导航没有什么不同,他就是一个UI元素而已,但是他很方便,普通,可以在其中放一些按钮然后通过按钮导航到其他页面(切换页面实际上是手动通过setRootpush实现的)。在应用中添加侧边菜单非常简单,这样像下面这样修改你的根组件的模板就可以了:

<ion-menu [content]="content">
    <ion-content>
        <ion-list>
            <button ion-item (click)="openPage(homePage)">
            Home
            </button>
        </ion-list>
    </ion-content>
</ion-menu>

<ion-nav id="nav" #content [root]="rootPage"></ion-nav>

我们使用<ion-menu>来创建一个菜单,同时也需要告诉它我们会附加什么上去。这个就是为什么我们将[content]属性设置为一个布局变量content,然后在<ion-nav>中添加#content来定义content。基本上这就是说<ion-nav>是我们的主要内容区域,我们想让内容在其中显示。

关于Ionic 2的导航多少其他的需要去学习的,但是只要你学好了本课程的这些基本知识,那么在大部分情况下你都不会有什么问题。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343

推荐阅读更多精彩内容