构建应用
We'll make use of the live reloading provided by the Ionic CLI.
$ ionic serve
Our Ionic App will have 3 main pages. One for github users, another for github organizations and another for github repositories. The last two pages are just views to show that we can navigate with the side bar, they will not have any content. The github users page, however, will enable you to view the details of the user.
Delete everything in the src/pages folder. Then we'll first quickly create the three main pages with help from the Ionic CLI. Run these in your terminal
$ ionic g page users
$ ionic g page repos
$ ionic g page organisations
This will create three folder with the respective names.g
is an alias forgenerate
, so you can still doionic generate page pageName
. Go into each of the folders and replace the content of the html files to look like this.
src/pages/users/users.html
<ion-header>
<ion-navbar>
<button ion-button icon-only menuToggle>
<ion-icon name="menu"></ion-icon>
</button>
<ion-title>
Users
</ion-title>
</ion-navbar>
</ion-header>
<ion-content padding>
<h3>Users view page</h3>
</ion-content>
src/pages/repos/repos.html
<ion-header>
<ion-navbar>
<button ion-button icon-only menuToggle>
<ion-icon name="menu"></ion-icon>
</button>
<ion-title>
Repos
</ion-title>
</ion-navbar>
</ion-header>
<ion-content padding>
<h3>Repos view page</h3>
</ion-content>
src/pages/organisations/organizations.html
<ion-header>
<ion-navbar>
<button menuToggle>
<ion-icon name="menu"></ion-icon>
</button>
<ion-title>Organisations</ion-title>
</ion-navbar>
</ion-header>
<ion-content padding>
<h3>Organizations view page</h3>
</ion-content>
Ionic 2 comes with some built in components.
The<ion-navbar>
is responsible for the navigation bar. We could say it's the navigation component in this case.
ion-button
is a built in directive for ionic 2 buttons. This instance has anicon-only
directive to show that this is an icon button.
menuToggle
is a built in directive to help toggle the side menu.
We then have<ion-icon>
, which is a component responsible for handling icons. We simply give it the icon name based onthis ionic icons list.
The<ion-title>
displays the page title.
The<ion-content>
holds the contents of the page. It has apadding
directive that provides a little padding to the contents.
Since we are thinking of these as pages, it would be nice to change the class names to have a page suffix in them. Update all the three generated pages typescript files to these.
src/pages/users.ts
import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';
@Component({
selector: 'page-users',
templateUrl: 'users.html'
})
export class UsersPage {
constructor(public navCtrl: NavController) {}
ionViewDidLoad() {
console.log('Hello Users Page');
}
}
src/pages/repos.ts
import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';
@Component({
selector: 'page-repos',
templateUrl: 'repos.html'
})
export class ReposPage {
constructor(public navCtrl: NavController) {}
ionViewDidLoad() {
console.log('Hello Repos Page');
}
}
src/pages/organisations.ts
import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';
@Component({
selector: 'page-organizations',
templateUrl: 'organisations.html'
})
export class OrganisationsPage {
constructor(public navCtrl: NavController) {}
ionViewDidLoad() {
console.log('Hello Organisations Page');
}
}
TheionViewDidLoad()
method is an ionic life cycle hook. It's fired once an ionic view has load. Intuitive, right?
We'll then add these pages to our side nav. Go tosrc/app/app.component.tsand we'll make a few chages. If you check closely there is a class property calledpages
. This is what composes the sidenav (ion-menu) view, as show in thesrc/app/app.html
<ion-menu [content]="content">
<ion-header>
<ion-toolbar>
<ion-title>Pages</ion-title>
</ion-toolbar>
</ion-header>
<ion-content>
<ion-list>
<button ion-item *ngFor="let p of pages" (click)="openPage(p)">
{{p.title}}
</button>
</ion-list>
</ion-content>
</ion-menu>
<ion-nav [root]="rootPage" #content swipeBackEnabled="false"></ion-nav>
We will not touch this file too, we will just use it as it was generated. The button has an*ngFor="let p of pages"
directive, this is how Angular 2 performs repeating in templates. It simply means loop through the_pages_collection and generate a template for each item in the collection. So if we change the value of thepages
property, we change the content of the sidenav (ion-menu).
The<ion-nav>
is where the page navigated to is displayed. Theroot
property is bound torootPage
in the page class. We'll see definition this in detail shortly.
To add the correct pages in the sidenav, we'll make a few changes to thesrc/app/app.component.tsfile. I have deleted two import statements (HelloIonicPage and ListPage) at the top for the pages we deleted, and added import statements for the pages we created.
src/app/app.component.ts
import { Component, ViewChild } from '@angular/core';
import { Platform, MenuController, Nav } from 'ionic-angular';
import { StatusBar } from 'ionic-native';
import { UsersPage } from '../pages/users/users';
import { ReposPage } from '../pages/repos/repos';
import { OrganisationsPage } from '../pages/organisations/organisations';
@Component({
templateUrl: 'app.html'
})
export class MyApp {
// Commented Out for Brevity
}
TheUsersPage
,ReposPage
andOrganisationsPage
are component classes that represent the pages that were scaffolded when we generated the individual pages. You can check them out insrc/pages/users/users.ts,src/pages/repos/repos.tsandsrc/pages/organisations/organisations.ts.
We'll then edit thepages
class property to match our new pages.
src/app/app.component.ts
// imports commented out for brevity
export class MyApp {
@ViewChild(Nav) nav: Nav;
// make UsersPage the root (or first) page
rootPage: any = UsersPage;
pages: Array<{title: string, component: any}>;
constructor(public platform: Platform, public menu: MenuController) {
this.initializeApp();
// set our app's pages
this.pages = [
{ title: 'Users', component: UsersPage },
{ title: 'Repos', component: ReposPage },
{ title: 'Organisations', component: OrganisationsPage },
];
}
initializeApp() {
this.platform.ready().then(() => {
// Okay, so the platform is ready and our plugins are available.
// Here you can do any higher level native things you might need.
StatusBar.styleDefault();
});
}
openPage(page) {
// close the menu when clicking a link from the menu
this.menu.close();
// navigate to the new page if it is not the current page
this.nav.setRoot(page.component);
}
}
Notice that therootPage
class property is set to theUsersPage
. Remember that in the viewsrc/app/app.htmlthe<ion-nav>
root property was bound to thisrootPage
. This means that the UsersPage will be shown first when the app loads.
We have changed the value ofthis.pages
in the constructor to match the pages that we added.
TheopenPage
method is responsible for opening pages when clicked. If you look back into thesrc/app/app.html, we can see that the list of pages of bound to this method with(click)="openPage(p)"
. Takes in a page, and opens it. Simple, right?
The final thing we need to do to finish this set up is tell angular about our pages. This is done in thesrc/app/app.module.tsfile.
Import all the three pages and add them to both thedeclarations_and the_entryComponents_properties of the@NgModule_. Delete the imports we are not using
src/app/app.module.ts
import { NgModule } from '@angular/core';
import { IonicApp, IonicModule } from 'ionic-angular';
import { MyApp } from './app.component';
import { UsersPage } from '../pages/users/users';
import { ReposPage } from '../pages/repos/repos';
import { OrganisationsPage } from '../pages/organisations/organisations';
@NgModule({
declarations: [
MyApp,
UsersPage,
ReposPage,
OrganisationsPage
],
imports: [
IonicModule.forRoot(MyApp)
],
bootstrap: [IonicApp],
entryComponents: [
MyApp,
UsersPage,
ReposPage,
OrganisationsPage
],
providers: []
})
export class AppModule {}
Running serve in the terminal then going tohttp://localhost:8100
should output the app.