[Ionic 2从入门到精通] 6.3 新建标签页布局

本课中我们给应用创建一个基本的布局,也就是一个标签页布局。标签页的工作方式跟之前的页面有点不一样,页面只是标签页的持有者,但是实际内容是你导入进来的其他标签页面。实际工作中看到的话你就会知道了。
首先,我们得创建三个子标签来持有应用的不用页,但是实际上我们有一个额外的标签也是用于持有Quick List功能的。
我们先从持有所有标签页的Home页开始。
>修改 src/pages/home/home.html 为如下:

<ion-tabs>
    <ion-tab [root]="tab1Root" tabTitle="Location" tabIcon="navigate"></ion-tab>
    <ion-tab [root]="tab2Root" tabTitle="My Details" tabIcon="person"></ion-tab>
    <ion-tab [root]="tab3Root" tabTitle="Camp Details" tabIcon="bookmarks"></ion-tab>
</ion-tabs>

如你所见,此处布局非常简单。我们用到了<ion-tabs>接着通过<ion-tab>设置了一些标签页。我们然后将这些标签页的root属性设置了一个表达式,这些表达式马上会在home.ts上定义。这个表达式将是标签页用来容纳的内容。我们也添加了title和icon用来展示在标签界面上。
现在,我们来看看类定义。
>修改 src/pages/home/home.ts 为如下:

import { Component } from '@angular/core';
import { LocationPage } from '../location/location';
import { MyDetailsPage } from '../my-details/my-details';
import { CampDetailsPage } from '../camp-details/camp-details';

@Component({
    selector: 'page-home',
    templateUrl: 'home.html'
})
export class HomePage {
    tab1Root: any = LocationPage;
    tab2Root: any = MyDetailsPage;
    tab3Root: any = CampDetailsPage;

    constructor(){

    }

}

我们导入了所有要在标签页中展示的页面,然后设置好了模板中要用到的表达式。第一个展示标签页展示的是LocationPage
我们的标签页基本上是设置好了(万岁!),但是还没到休息时间 -- 我们需要给每个标签页设置好类。我们先从Location页开到。Location页面有一个地图,一些按钮给用户设置他们位置,给用户启动回家导航。
>修改 src/pages/location/location.html 为如下:

<ion-header>
    <ion-navbar color="primary">
        <ion-title>
            <img src = "assets/images/logo.png" class="logo" />
        </ion-title>
        <ion-buttons start>
            <button ion-button icon-only (click)="setLocation()"><ion-icon name="pin"></ion-icon></button>
        </ion-buttons>
        <ion-buttons end>
            <button ion-button icon-only (click)="takeMeHome()"><ion-icon name="walk"></ion-icon></button>
        </ion-buttons>
    </ion-navbar>
</ion-header>

<ion-content>

    <div #pleaseConnect id="please-connect">
        <p>Please connect to the Internet...</p>
    </div>

    <div #map id="map"></div>
</ion-content>

<ion-navbar>允许我们在应用顶部添加一个页首用于持有按钮,标题甚至在需要的时候直接整合Ionic导航系统的后退按钮。我们给他添加了primary属性用我们的primary颜色对他定制样式,这个颜色在app.variable.scss定义好了(我们后面会配置)。
在这个navbar里面我们用到了<ion-title>,他就是用来展示当前页标题和logo的。我们给他提供了start属性,这样按钮都会从左边开始排列,如果是right属性的话就是从右边开始排列。我们在两边各放置了一个按钮用处触发“设置位置”和“带我回家”功能。
最后,内容区域只有一个div我们在其中添加了#map -- 这让我们后面可以在类中获取到这个节点。同时div稍后也会作为我们Google Map的容器。我们添加了另一个div用来展示用户的连接信息告诉用户是否联网了(稍后实现这个)。
现在,我们来看看location页的类定义。
>修改 src/pages/location/location.ts 为如下:

import { NavController, Platform, AlertController } from 'ionic-angular';
import { Component, ElementRef, ViewChild } from '@angular/core';
import { Geolocation } from 'ionic-native';
import { GoogleMaps } from '../../providers/google-maps';
import { Data } from '../../providers/data';

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

    @ViewChild('map') mapElement: ElementRef;
    @ViewChild('pleaseConnect') pleaseConnect: ElementRef;

    latitude: number;
    longitude: number;
    constructor(public navCtrl: NavController, public maps: GoogleMaps, public platform: Platform, public dataService: Data, public alertCtrl:AlertController) {
    }

    ionViewDidLoad(): void {
    }

    setLocation(): void {
    }

    takeMeHome(): void {
    }
}

虽然我们设置了一些东西,但是还不足以继续。我们从Ionic Native中导入了稍后会用到的Geolocation,同样也导入了Google Maps和Data服务(稍后创建)。
我们把所有这些服务都注入到构造器中通过添加public将他们设置为成员变量,我们也定义了两个变量latitudelongitude,将用于持有用户位置。最后,我们添加了两个模板中按钮要调用的函数,目前还没有实现。
这里最奇怪的是使用了@ViewChild。你可以用他来获取模板中的元素的引用。所以,如果我们这样:

@ViewChild('map') mapElement: ElementRef;

他将会去location.html模板中查找一个含有#map的元素。如果找到了的话,将会返回一个ElementRef也就是那个元素的引用。在这个实例中,我们将这个引用指向到了mapElement。稍后,我们会把这个引用传递给Google Maps提供者。重点记住,这一步需要在ionViewDidLoad()方法里面做,因为这个函数只会在DOM(页面元素)完全加载完成的时候运行一次。
现在,我们移步到Camp Details页。
> 修改 src/pages/camp-details/camp-details.html 页面为如下:

<ion-header>
    <ion-navbar color="primary">
        <ion-title>
            <img src="assets/images/logo.png" class="logo" />
        </ion-title>
    </ion-navbar>
</ion-header>

<ion-content padding>
    <ion-card>
        <ion-card-header>
            Camp Details
        </ion-card-header>

        <ion-card-content>
        Update this form with the details of your current camp so you have an
        easy reference for later.
        </ion-card-content>
    </ion-card>
    <ion-list no-lines>

        <ion-item>
            <ion-label stacked>Gate Access Code</ion-label>
            <ion-input type="text"></ion-input>
        </ion-item>

        <ion-item>
            <ion-label stacked>Ammenities Code</ion-label>
            <ion-input type="text"></ion-input>
        </ion-item>

        <ion-item>
            <ion-label stacked>WiFi Password</ion-label>
            <ion-input type="text"></ion-input>
        </ion-item>

        <ion-item>
            <ion-label stacked>Phone Number</ion-label>
            <ion-input type="text"></ion-input>
        </ion-item>

        <ion-item>
            <ion-label stacked>Departure Date</ion-label>
            <ion-datetime displayFormat="DD/MM/YYYY"></ion-datetime>
        </ion-item>

        <ion-item>
            <ion-label stacked>Notes</ion-label>
            <ion-textarea type="text"></ion-textarea>
        </ion-item>

    </ion-list>
</ion-content>

第一个就是添加了navbar,你已经知道他是怎么工作的。我们也用了一个<ion-card>为页面创建了一个小小的页首区用于描述页面上干嘛用的,这只是一个纯粹的装饰品。然后我们在一个列表里面有大量的输入域。不是用的标准HTML语法:

<input type="text" />

我们使用的是Ionic提供的<ion-input>,但是接受的是同样的类型(你应该注意到了最后一个是<ion-textarea>)。我们提供了stacked属性,这个属性让在输入域上“堆栈”标签,但是Ionic默认给输入域提供的样式有很多。目前我们只是给输入域添加了标签,稍后回来我们会其他一些其他的东西这样我们就可以获取用户的输入。
同时这里我们也有用到<ion-datetime>,这是Ionic提供的内置的日期和时间选择器。
现在没有什么不同的事情会发生,我们还是先来创建页的类定义吧。
> 修改 src/pages/camp-details/camp-details.ts 如下:

import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { Data } from '../../providers/data';

@Component({
    selector: 'page-camp-details',
    templateUrl: 'camp-details.html'
})
export class CampDetailsPage {

    constructor(public navCtrl: NavController, public formBuilder: FormBuilder,public dataService: Data) {
    }

    saveForm(): void {
    }
}

这里跟之前不同的是我们从Angular导入了FormBuilderValidators。就跟上面说的一样,我们将编辑稍后创建的输入域来做一些实际的事情,这就是Form Builder(和ControlGroup)用来介入的地方了。Form Builder允许你创建和管理表单,Vlidators可以附加到指定的输入域以确保输入的是一个有效值(即,如果需要输入的是邮件地址,手机号等)。我们稍后再深入。
我们也添加了一个saveForm函数稍后用来保存用户在表单中的输入值。现在,我们移步到My Details页,跟这个页面很像。
> 修改 src/pages/my-details/my-details.html 页面为如下:

<ion-header>
    <ion-navbar color="primary">
        <ion-title>
            <img src = "assets/images/logo.png" class="logo" />
        </ion-title>
    </ion-navbar>
</ion-header>

<ion-content padding>
    <ion-card>
        <ion-card-header>
        My Details
        </ion-card-header>

        <ion-card-content>
        Update this form with your details so you have an easy reference for
        later.
        </ion-card-content>
    </ion-card>

    <ion-list no-lines>
        <ion-item>
        <ion-label stacked>Car Registration</ion-label>
        <ion-input type="text"></ion-input>
        </ion-item>

        <ion-item>
        <ion-label stacked>Trailer Registration</ion-label>
        <ion-input type="text"></ion-input>
        </ion-item>

        <ion-item>
        <ion-label stacked>Trailer Dimensions</ion-label>
        <ion-input type="text"></ion-input>
        </ion-item>

        <ion-item>
        <ion-label stacked>Phone Number</ion-label>
        <ion-input type="text"></ion-input>
        </ion-item>

        <ion-item>
        <ion-label stacked>Notes</ion-label>
        <ion-textarea type="text"></ion-textarea>
        </ion-item>
    </ion-list>
</ion-content>

没啥好解释的,只是有几个不同的输入域,他跟Camp Detail模板简直就是一毛一样。直接去类定义吧。
> 修改 src/pages/my-details/my-details.ts 如下:

import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { Data } from '../../providers/data';

@Component({
    selector: 'page-my-details',
    templateUrl: 'my-details.html'
})
export class MyDetailsPage {
    constructor(public navCtrl: NavController, public formBuilder: FormBuilder, public dataService: Data) {

    }
    saveForm(): void {
    }
}

同样,这个跟Camp Details页基本一毛一样的。为这个枯燥的结局道个歉,但是对于布局部分来讲,这就是全部了,下一刻我们将近距离观察Form Builder以及让我们让你合理的输入。

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

推荐阅读更多精彩内容