一、Ionic2提供了一个简单的启动模板来快速支撑一个app,我们的app叫做githubIonic。
在你的终端:
$ ionic start githubIonic tutorial --v2 --ts
www/index.html一般是app的入口程序。
<!DOCTYPE html>
<html lang="en">
<head>
<title>Ionic</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
<link ios-href="build/css/app.ios.css" rel="stylesheet">
<link md-href="build/css/app.md.css" rel="stylesheet">
<link wp-href="build/css/app.wp.css" rel="stylesheet">
</head>
<body>
<ion-app></ion-app>
<!-- cordova.js required for cordova apps -->
<script src="cordova.js"></script>
<!-- Polyfill needed for platforms without Promise and Collection support -->
<script src="build/js/es6-shim.min.js"></script>
<!-- Zone.js and Reflect-metadata -->
<script src="build/js/Reflect.js"></script>
<script src="build/js/zone.js"></script>
<!-- the bundle which is built from the app's source code -->
<script src="build/js/app.bundle.js"></script>
</body>
</html>
我们一般不会碰这里面的文件,注意<ion-app></ion-app>:这是我们程序的入口,这叫做我们程序的根组件
我们将使用lonic CLI来重新加载。
我们的Ionic将有三个主要页面,一个对于github的用户,一个对于github组织,另一个用户github库,最后两页视图只是用来显示我们可以与侧边栏导航,他们讲没有任何内容,但是,github用户界面将使你可以查看用户的详细信息。
删除app/pages下所有文件夹,并且清空app/theme/app.core.scss文件,我们可以用以下命令快速创造三个页面。
$ ionic g page users
$ ionic g page repos
$ ionic g page organizations
ioinc generate pageName
user.html
<ion-header>
<ion-navbar>
<button 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>
<ion-header>
<ion-navbar>
<button menuToggle>
<ion-icon name="menu"></ion-icon>
</button>
<ion-title>Users</ion-title>
</ion-navbar>
</ion-header>
<ion-content padding >
<h3>Repos view page</h3>
</ion-content>
<ion-header><pre name="code" class="html">import {Component, ViewChild} from '@angular/core';
import {ionicBootstrap, Platform, MenuController, Nav} from 'ionic-angular';
import {StatusBar} from 'ionic-native';
// Comment out impor of pages we have deleted from the pages folder
//import {HelloIonicPage} from './pages/hello-ionic/hello-ionic';
//import {ListPage} from './pages/list/list';
import {UsersPage} from './pages/users/users';
import {ReposPage} from './pages/repos/repos';
import {OrganizationsPage} from './pages/organizations/organizations'
@Component({
templateUrl: 'build/app.html'
})
class MyApp {
// Commented out for brevity
}
<ion-navbar>负责导航栏,即一个导航组件。
menuToggle是用来做一个切换菜单的指令。
<ion-icon>负责处理图标,我们简单的给他取个名字。
<ion-title>展示页面标题
<ion-content>负责处理页面的的内容,并且其中有一个padding来表明有一点padding
现在我们把这些文件添加到导航,并且来到app/app.ts,我们会做一点改变,其中有个属性叫做pages,这就是显示在app.htmlde的导航视图。
<ion-menu [content]="content">
<ion-toolbar>
<ion-title>Pages</ion-title>
</ion-toolbar>
<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 id="nav" [root]="rootPage" #content swipe-back-enabled="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 the pages property, we change the content of the side nav.
<ion-nav>是显示页面导航,root属性绑定了rootpage,
import {Component, ViewChild} from '@angular/core';
import {ionicBootstrap, Platform, MenuController, Nav} from 'ionic-angular';
import {StatusBar} from 'ionic-native';
// Comment out impor of pages we have deleted from the pages folder
//import {HelloIonicPage} from './pages/hello-ionic/hello-ionic';
//import {ListPage} from './pages/list/list';
import {UsersPage} from './pages/users/users';
import {ReposPage} from './pages/repos/repos';
import {OrganizationsPage} from './pages/organizations/organizations'
@Component({
templateUrl: 'build/app.html'
})
class MyApp {
// Commented out for brevity
}
接下来我们将编辑页面属性来匹配我们的新界面。
app.ts:
class MyApp {
@ViewChild(Nav) nav: Nav;
// make UsersPage the root (or first) page
// rootPage: any = UsersPage;
rootPage: any = UsersPage;
pages: Array<{title: string, component: any}>;
constructor(
private platform: Platform,
private menu: MenuController
) {
this.initializeApp();
// set our app's pages
this.pages = [
// Comment out pages we deleted
//{ title: 'Hello Ionic', component: HelloIonicPage },
//{ title: 'My First List', component: ListPage }
{ title: 'Users', component: UsersPage },
{ title: 'Repos', component: ReposPage },
{ title: 'Organizations', component: OrganizationsPage }
];
}
// code commented out for brevity
}
我们可以获取Github用户从https://api.github.com/users,这个页面列出了大概30个json格式的github用户。
首先,我们需要创建一个用户模型,这个类是有我们所需要的用户字段,在项目中创建一个model文件夹,在这里面放置了以后我们想要的模型,在里面添加一个app/user.ts。
export class User {
login: string;
id: number;
avatar_url: string;
gravatar_id: string;
url: string;
html_url: string;
followers_url: string;
following_url: string;
gists_url: string;
starred_url: string;
subscriptions_url: string;
repos_url: string;
events_url: string;
received_events_url: string;
type: string;
site_admin: boolean;
name: string;
company: string;
blog: string;
location: string;
email: string;
hireable: string;
bio: string;
public_repos: number;
public_gists: number;
followers: number;
following: number;
created_at: string;
updated_at: string;
}
ionic g provider github-users
import { Injectable } from '@angular/core';
import { Http } from '@angular/http';
import 'rxjs/add/operator/map';
/*
Generated class for the GithubUsers provider.
See https://angular.io/docs/ts/latest/guide/dependency-injection.html
for more info on providers and Angular 2 DI.
*/
import {User} from '../../models/user'
@Injectable()
export class GithubUsers {
githubUsers:any =null;
constructor(private http: Http) {}
load(){
if(this.githubUsers){
//已经加载user
return Promise.resolve(this.githubUsers);
}
//还没有加载user
return new Promise(resolver => {
// 我们正在使用Angular Http Provider来请求users
//响应后把json的数据映射到json对象
//在这之后处理user及其数据
this.http.get('https://api.github.com/users')
.map(res => <Array<Users>>(res.json()))
.subscribe(users => {
this.githubUsers=users;
resolver(this.githubUsers);
});
});
}
}
我们做的第一件事情是导入用户模型,然后注意load()这个方法,它替你加载了你想要的所有数据,你需要做的是输入json的路径,在本例中是....,并在某处调用GithubUsers.load。
最后,我们想要结果转化成一个user数组,我们通过map(res => <Array<Users>(res.json())>)来处理。
三、显示github用户
现在我们有自己的用户,可以让其显示出来,在这之前,我们需要测试是否需要从provider获取数据。
打开app/page/users/user.ts文件
import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';
// Import GithubUsers provider
import {GithubUsers} from '../../providers/github-users/github-users';
/*
Generated class for the UsersPage page.
See http://ionicframework.com/docs/v2/components/#navigation for more info on
Ionic pages and navigation.
*/
@Component({
templateUrl: 'build/pages/users/users.html',
// Add the GithubUsers provider as part of our page component
providers: [GithubUsers]
})
export class UsersPage {
// Inject the GithubUsers in the constructor of our page component
constructor(public nav: NavController, githubUsers: GithubUsers) {
// Test whether the github provider returns data
githubUsers
.load()
.then(function (users) {
// Log the returned github users
console.log(users)
});
}
}
[GithubUsers]是其中一种属性。
并且在UserPage的构造方法中,我们添加了githubUsers: GithubUsers作为其中一个参数,这就是如何在Angular 2中注入依赖,然后我们在构造函数中调用Load方法并且使用console.log(user)记录结果。
为了显示users在我们的页面上,我们需要在UserPage中有个局部变量,也就是一个user的数组,并且用于更新UserPage。
app/pages/users/user.ts
// Imports commented out for brevity
// Import User model
import {User} from '../../models/user';
@Component({
// Commented out for brevity
})
export class UsersPage {
// Declare users as an array of User model
users: User[];
// Inject the GithubUsers in the constructor of our page component
constructor(public nav: NavController, githubUsers: GithubUsers) {
// Test whether the github provider returns data
githubUsers
.load()
// User arrow function notation
.then(users => this.users = users);
}
}
<ion-header>
<ion-navbar>
<button menuToggle>
<ion-icon name="menu"></ion-icon>
</button>
<ion-title>Users</ion-title>
</ion-navbar>
</ion-header>
<ion-content padding>
<ion-list>
<button ion-item *ngFor="let user of users">
<ion-avatar item-left>
<img [src]="user.avatar_url">
</ion-avatar>
<h2>{{ user.login }}</h2>
<ion-icon ios="ios-arrow-forward" md="md-arrow-forward" item-right></ion-icon>
</button>
</ion-list>
</ion-content>
接下来,user在ion-avatar里面绑定用户属性,就是给图像添加一个边界,因为属性中有一个avatar_url,因此user.avatar_url。接下来再添加user.login。而ion-icon是用来加载图片的,你可以简单的使用<ion-icon name="arrow -forward"></ion-icon>,但是我们使用ios="ios-arrow-forward" md="md-arrow-forward"来演示如何使用特定平台的图标,如android和ios。
四、显示用户详情
接下来,我们将创建一个展示用户详情的页面。
<ion-header>
<ion-navbar>
<button menuToggle>
<ion-icon name="menu"></ion-icon>
</button>
<ion-title>{{login}} Details</ion-title>
</ion-navbar>
</ion-header>
<ion-content padding >
<h3>User Details view page</h3>
</ion-content>
// Imports commented out for brevity
// Import User's Details Page
import {UserDetailsPage} from '../user-details/user-details';
@Component({
// Code commented out for brevity
})
export class UsersPage {
// Code commented out for brevity
constructor(public nav: NavController, githubUsers: GithubUsers) {
// Implementation commented out for brevity
}
// Navigate to user details page with the login as a parameter
goToDetails(event, login) {
this.nav.push(UserDetailsPage, {
login: login
});
}
}
app/page/user/user.html
<!-- HTML commented out for brevity -->
<ion-content padding>
<ion-list>
<button ion-item *ngFor="let user of users" (click)="goToDetails($event, user.login)">
<!-- HTML commented out for brevity -->
</button>
</ion-list>
</ion-content>
import { Component } from '@angular/core';
// Add NavParams to get the naviagtion parameters
import { NavController, NavParams } from 'ionic-angular';
/*
Generated class for the UserDetailsPage page.
See http://ionicframework.com/docs/v2/components/#navigation for more info on
Ionic pages and navigation.
*/
@Component({
templateUrl: 'build/pages/user-details/user-details.html',
})
export class UserDetailsPage {
login: string;
constructor(public nav: NavController, navParams: NavParams) {
// Retrieve the login from the navigation parameters
this.login = navParams.get('login');
}
}
之后,声明String类型的type。
我们把NavParmas provider注入构造参数,这让我们获得上一页传进来的参数,通过this.login = navParams.get('login')。
五、得到更多的用户细节
现在我们已经有了用户详细信息,我们需要他的具体的细节,要做到这一点,我们必须编辑GithubUser provider来处理请求,请求应该改成https://api.github.com/users/{login},最后面的参数是我们要传递进去的username/login.。
app/providers/github-users/github-users.ts
// Imports commented out for brevity
@Injectable()
export class GithubUsers {
githubUsers: any = null;
constructor(public http: Http) {}
load() {
// Implementation commented out for brevity
}
// Get user details from the github api
loadDetails(login: string) {
// get the data from the api and return it as a promise
return new Promise<User>(resolve => {
// Change the url to match https://api.github.com/users/{username}<pre name="code" class="html"><ion-content padding>
<ion-searchbar></ion-searchbar>
<ion-list>
<!--HTML commented out for brevity-->
</ion-list>
</ion-content>
我们添加了一个loadDetails()方法,他接收一个字符串作为参数,并且返回一个promise类型的用户,因此返回一个new Promise<User>
六、添加搜索栏
这是我们应用程序的最后一个功能,我们会添加一个搜索栏,Ionic提供了一个自定义seachbar组件供我们使用。
app/pages/users/users.html
<ion-content padding>
<ion-searchbar></ion-searchbar>
<ion-list>
<!--HTML commented out for brevity-->
</ion-list>
</ion-content>
https://api.github.com/search/users?q={searchParam}。
首先,我们创建一个provider方法来搜索在GithubUser中。
// Imports commented out for brevity
@Injectable()
export class GithubUsers {
// Code commented out for brevity
load() {
// Method implementation commented out for brevity
}
// Get user details from the github api
loadDetails(login: string) {
// Method implementation commented out for brevity
}
// Search for github users
searchUsers(searchParam: string) {
// get the data from the api and return it as a promise
return new Promise<Array<User>>(resolve => {
// Change the url to match https://api.github.com/search/users?q={searchParam}
this.http.get(`https://api.github.com/search/users?q=${searchParam}`)
// Cast the result into an array of users.
// The returned json result has an items
// property which contains the users
.map(res => <Array<User>>(res.json().items))
.subscribe(users => {
resolve(users);
});
});
}
}
// Imports commented out for brevity
@Component({
// Code commented out for brevity
})
export class UsersPage {
// Code commented out for brevity
// Inject the GithubUsers in the constructor of our page component
constructor(public nav: NavController, githubUsers: GithubUsers) {
// Code commented out for brevity
// Test if our seach function works.
githubUsers
.searchUsers('ganga')
.then(users => console.log(users));
}
// Code commented out for brevity
}
我们只有当超过三个字符时才开始查询。
让我们来获取用户输入searchbar的值。
app/pages/users/user.html
<ion-content padding >
<ion-searchbar (input)="search($event)"></ion-searchbar>
<ion-list>
<!-- HTML commented out for brevity -->
</ion-list>
</ion-content>
// Imports commented out for brevity
@Component({
// Commented out for brevity
})
export class UsersPage {
// Commented out for brevity
// Inject the GithubUsers in the constructor of our page component
constructor(public nav: NavController, private githubUsers: GithubUsers) {
// Implementation commented out for brevity
}
// Search for user's from github
// Handle input event from search bar
search(searchTerm) {
let term = searchTerm.target.value;
// We will only perform the search if we have 3 or more characters
if (term.trim() == '' || term.trim().length < 3) {
// Get github users and assign to local user's variable
this.githubUsers
.load()
// Load original users in this case
.then(users => this.users = users)
} else {
// Get the searched users from github
this.githubUsers.searchUsers(term)
.then(users => this.users = users)
}
}
}