第三课:新建一个标签页布局
本课中我们给应用创建一个基本的布局,也就是一个标签页布局。标签页的工作方式跟之前的页面有点不一样,页面只是标签页的持有者,但是实际内容是你导入进来的其他标签页面。实际工作中看到的话你就会知道了。
首先,我们得创建三个子标签来持有应用的不用页,但是实际上我们有一个额外的标签也是用于持有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>
如你所见,此处布局非常简单。我们用到了
现在,我们来看看类定义。
>修改 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>
在这个navbar里面我们用到了
最后,内容区域只有一个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将他们设置为成员变量,我们也定义了两个变量latitude和longitude,将用于持有用户位置。最后,我们添加了两个模板中按钮要调用的函数,目前还没有实现。
这里最奇怪的是使用了@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,你已经知道他是怎么工作的。我们也用了一个
<input type="text" />
我们使用的是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导入了FormBuilder和Validators。就跟上面说的一样,我们将编辑稍后创建的输入域来做一些实际的事情,这就是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以及让我们让你合理的输入。