1、新建一个空的ionic2项目
ionic start todo-roles blank --v2
cd todo-roles
cnpm install
2、添加 登录和注册页面
ionic g page LoginPage
ionic g page SignupPage
3、添加服务
ionic g provider Auth --身份验证的服务
ionic g provider Todos --取数据的服务
4、把刚添加的登录、注册页面以及服务 引入 src/app/app.module.ts
并且同时import Storage
import { NgModule, ErrorHandler } from '@angular/core';
import { IonicApp, IonicModule, IonicErrorHandler } from 'ionic-angular';
import { MyApp } from './app.component';
import { HomePage } from '../pages/home/home';
import {Storage} from '@ionic/storage';
import {LoginPage} from '../pages/login-page/login-page';
import {SignupPage} from '../pages/signup-page/signup-page';
import {Todos} from '../providers/todos';
import {Auth} from '../providers/auth';
@NgModule({
declarations: [
MyApp,
HomePage,
LoginPage,
SignupPage
],
imports: [
IonicModule.forRoot(MyApp)
],
bootstrap: [IonicApp],
entryComponents: [
MyApp,
HomePage,
LoginPage,
SignupPage
],
providers: [{provide: ErrorHandler, useClass: IonicErrorHandler},Storage,Todos,Auth]
})
export class AppModule {}
5、修改验证服务的代码(src/providers/auth.ts)
import { Injectable } from '@angular/core';
import { Http,Header } from '@angular/http';
import {Storage } from '@ionic/storage';
import 'rxjs/add/operator/map';
@Injectable()
export class Auth {
public token:any;
public baseUrl:string="https://www.xxx.com/api/";
constructor(public http: Http,public storage:Storage) {
}
checkAuthentication(){
return new Promise((resolve,reject)=>{
//加载token
this.storage.get('token').then((value)=>{
this.token=value;
let headers=new Headers();
headers.append('Authorization',this.token);
//去服务端验证token是否正确
this.http.get(this.baseUrl+'auth/protected',{headers:headers})
.subscribe(res=>{
resolve(res);
},(err)=>{
reject(err);
});
});
});
}
createAccount(details){
return new Promise((resolve, reject) => {
let headers = new Headers();
headers.append('Content-Type', 'application/json');
this.http.post(this.baseUrl+'auth/register', JSON.stringify(details), {headers: headers})
.subscribe(res => {
let data = res.json();
this.token = data.token;
this.storage.set('token', data.token);
resolve(data);
}, (err) => {
reject(err);
});
});
}
login(credentials){
return new Promise((resolve, reject) => {
let headers = new Headers();
headers.append('Content-Type', 'application/json');
this.http.post(this.baseUrl+'/auth/login', JSON.stringify(credentials), {headers: headers})
.subscribe(res => {
let data = res.json();
this.token = data.token;
this.storage.set('token', data.token);
resolve(data);
resolve(res.json());
}, (err) => {
reject(err);
});
});
}
logout(){
this.storage.set('token', '');
}
}
6、页面一开始要加载登录页面,如果token已经存在,则直接进入主页面,所以修改src/app/app.component.ts
import { Component } from '@angular/core';
import { Platform } from 'ionic-angular';
import { StatusBar, Splashscreen } from 'ionic-native';
import { LoginPage } from '../pages/home/home';
@Component({
templateUrl: 'app.html'
})
export class MyApp {
rootPage = LoginPage;
constructor(platform: Platform) {
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();
Splashscreen.hide();
});
}
}
7、完善登录页面
src/pages/login-page/login-page.html
<ion-header>
<ion-navbar color="secondary">
<ion-title>Shared Todos</ion-title>
</ion-navbar>
</ion-header>
<ion-content>
<ion-row class="login-form">
<ion-col>
<ion-list inset>
<ion-item>
<ion-label><ion-icon name="person"></ion-icon></ion-label>
<ion-input [(ngModel)]="email" placeholder="email" type="text"></ion-input>
</ion-item>
<ion-item>
<ion-label><ion-icon name="lock"></ion-icon></ion-label>
<ion-input [(ngModel)]="password" placeholder="password" type="password"></ion-input>
</ion-item>
</ion-list>
<button ion-button full (click)="login()" color="primary" class="login-button">Login</button>
</ion-col>
</ion-row>
<ion-row>
<ion-col>
<button ion-button (click)="launchSignup()" class="create-account">Create an Account</button>
</ion-col>
</ion-row>
</ion-content>
src/pages/login-page/login-page.ts
import { Component } from '@angular/core';
import { NavController, LoadingController } from 'ionic-angular';
import {Auth} from '../../providers/auth';
import {HomePage} from '../home/home';
import {SignupPage} from '../signup-page/signup-page';
@Component({
selector: 'login-page',
templateUrl: 'login-page.html'
})
export class LoginPage {
email:string;
password:string;
loading:any;
constructor(public navCtrl: NavController, public authService: Auth,public loadingCtrl:LoadingController) {}
ionViewDidLoad() {
this.showLoader();
//Check if already authenticated
this.authService.checkAuthentication().then((res) => {
console.log("Already authorized");
this.loading.dismiss();
this.navCtrl.setRoot(HomePage); //跳转到主页面
}, (err) => {
console.log("Not already authorized");
this.loading.dismiss();
});
}
login(){
this.showLoader();
let credentials = {
email: this.email,
password: this.password
};
this.authService.login(credentials).then((result) => {
this.loading.dismiss();
console.log(result);
this.navCtrl.setRoot(HomePage);
}, (err) => {
this.loading.dismiss();
console.log(err);
});
}
launchSignup(){
this.navCtrl.push(SignupPage);
}
showLoader(){
this.loading = this.loadingCtrl.create({
content: 'Authenticating...'
});
this.loading.present();
}
}
src/pages/login-page/login-page.scss
.ios, .md {
login-page {
ion-content {
background-color: map-get($colors, secondary);
}
scroll-content {
display: flex;
flex-direction: column;
}
ion-row {
align-items: center;
text-align: center;
}
ion-item {
border-radius: 30px !important;
padding-left: 10px !important;
margin-bottom: 10px;
background-color: #f6f6f6;
opacity: 0.7;
font-size: 0.9em;
}
ion-list {
margin: 0;
}
.login-logo {
flex: 2;
}
.login-form {
flex: 1;
}
.create-account {
color: #fff;
text-decoration: underline;
background: none;
}
.login-button {
border-radius: 30px;
font-size: 0.9em;
background-color: transparent;
border: 1px solid #fff;
}
}
}
8、完善注册页面
src/pages/signup-page/signup-page.html
<ion-header>
<ion-navbar color="secondary">
<ion-title>Create Account</ion-title>
</ion-navbar>
</ion-header>
<ion-content padding>
<ion-row class="account-form">
<ion-col>
<ion-list inset>
<ion-item>
<ion-label><ion-icon name="mail"></ion-icon></ion-label>
<ion-input [(ngModel)]="email" placeholder="Email" type="email"></ion-input>
</ion-item>
<ion-item>
<ion-label><ion-icon name="lock"></ion-icon></ion-label>
<ion-input [(ngModel)]="password" placeholder="Password" type="password"></ion-input>
</ion-item>
<ion-item>
<ion-label>Role</ion-label>
<ion-select [(ngModel)]="role">
<ion-option value="reader">Reader</ion-option>
<ion-option value="creator">Creator</ion-option>
<ion-option value="editor">Editor</ion-option>
</ion-select>
</ion-item>
</ion-list>
<button ion-button (click)="register()" class="continue-button">Register</button>
</ion-col>
</ion-row>
</ion-content>
src/pages/signup-page/signup-page.ts
import { Component } from '@angular/core';
import { NavController, LoadingController } from 'ionic-angular';
import { Auth } from '../../providers/auth';
import { HomePage } from '../home/home';
@Component({
selector: 'signup-page',
templateUrl: 'signup-page.html'
})
export class SignupPage {
role: string;
email: string;
password: string;
constructor(public navCtrl: NavController, public authService: Auth, public loadingCtrl: LoadingController) {
}
register(){
this.showLoader();
let details = {
email: this.email,
password: this.password,
role: this.role
};
this.authService.createAccount(details).then((result) => {
this.loading.dismiss();
console.log(result);
this.navCtrl.setRoot(HomePage);
}, (err) => {
this.loading.dismiss();
});
}
showLoader(){
this.loading = this.loadingCtrl.create({
content: 'Authenticating...'
});
this.loading.present();
}
}
src/pages/signup-page/signup-page.scss
.ios, .md {
signup-page {
ion-content {
background-color: map-get($colors, secondary);
}
scroll-content {
display: flex;
flex-direction: column;
}
ion-item {
border-radius: 30px !important;
padding-left: 10px !important;
margin-bottom: 10px;
background-color: #f6f6f6;
opacity: 0.7;
font-size: 0.9em;
}
ion-list {
margin: 0;
}
.heading-text {
flex: 1;
align-items: center;
text-align: center;
}
.heading-text h3 {
color: #fff;
}
.account-form {
flex: 1;
}
.continue-button {
width: 100%;
border-radius: 30px;
margin-top: 30px;
font-size: 0.9em;
background-color: transparent;
border: 1px solid #fff;
}
}
}
9、完善Todos主界面
首先完善服务 src/providers/todos.ts
import { Injectable } from '@angular/core';
import { Http,Headers } from '@angular/http';
import {Auth } from './auth';
import 'rxjs/add/operator/map';
@Injectable()
export class Todos {
baseUrl="http://192.168.3.254:8888/api/";
constructor(public http: Http,public authService:Auth) {
}
getTodos(){
return new Promise((resolve,reject)=>{
let headers=new Headers();
headers.append('Authorization',this.authService.token);
this.http.get(this.baseUrl+'todos',{headers:headers})
.map(res=>res.json())
.subscribe(data=>{
resolve(data);
},(err)=>{
reject(err);
});
});
}
createTodo(todo) {
return new Promise((resolve,reject)=>{
let headers=new Headers();
headers.append('Content-Type','application/json');
headers.append('Authorization', this.authService.token);
this.http.post(this.baseUrl+'todos',JSON.stringify(todo),{headers:headers})
.map(res=>res.json())
.subscribe(res=>{
resolve(res);
},(err)=>{
reject(err);
});
});
}
deleteTodo(id){
return new Promise((resolve,reject)=>{
let headers=new Headers();
headers.append('Authorization', this.authService.token);
this.http.delete(this.baseUrl+'todos/' + id, {headers: headers}).subscribe((res) => {
resolve(res);
}, (err) => {
reject(err);
});
});
}
}
html界面 src/pages/home/home.html
<ion-header>
<ion-navbar color="secondary">
<ion-title>
Todo Roles
</ion-title>
<ion-buttons end>
<button ion-button icon-only (click)="addTodo()"><ion-icon name="add"></ion-icon></button>
</ion-buttons>
<ion-buttons start>
<button ion-button icon-only (click)="logout()"><ion-icon name="power"></ion-icon></button>
</ion-buttons>
</ion-navbar>
</ion-header>
<ion-content>
<ion-list no-lines>
<ion-item-sliding *ngFor="let todo of todos">
<ion-item>
{{todo.title}}
</ion-item>
<ion-item-options>
<button ion-button color="danger" (click)="deleteTodo(todo)">
<ion-icon name="trash"></ion-icon>
Delete
</button>
</ion-item-options>
</ion-item-sliding>
</ion-list>
</ion-content>
src/pages/home/home.ts
import { Component } from '@angular/core';
import { NavController,ModalController,AlertController,LoadingController } from 'ionic-angular';
import {Todos} from '../../providers/todos';
import {Auth} from '../../providers/auth';
import {LoginPage} from '../login-page/login-page';
@Component({
selector: 'home-page',
templateUrl: 'home.html'
})
export class HomePage {
todos:any;
loading:any;
constructor(public navCtrl: NavController,public todoService:Todos,public modalCtrl:ModalController,public alertCtrl:AlertController,public authService:Auth,public loadingCtrl:LoadingController) {
}
ionViewDidLoad(){
this.todoService.getTodos().then((data)=>{
this.todos=data;
},(err)=>{
console.log("not allowed");
})
}
addTodo(){
let prompt=this.alertCtrl.create({
title:'Add Todo',
message:'Describe your todo below',
inputs:[{
name:'title'
}],
buttons:[
{text:'Cancel'},
{text:'Save',handler:todo=>{
if(todo){
this.showLoader();
this.todoService.createTodo(todo).then((result)=>{
this.loading.dismiss();
this.todos=result;
console.log("Todo created");
},(err)=>{
this.loading.dismiss();
console.log("not allowed");
});
}
}}
]
});
prompt.present();
}
deleteTodo(todo){
this.showLoader();
//Remove from database
this.todoService.deleteTodo(todo._id).then((result)=>{
this.loading.dismiss();
//Remove locally
let index=this.todos.indexOf(todo);
if(index>-1){
this.todos.splice(index,1);
}
},(err)=>{
this.loading.dismiss();
console.log("not allowed");
});
}
showLoader(){
this.loading=this.loadingCtrl.create({
content:'Authenticating...'
});
this.loading.present();
}
logout(){
this.authService.logout();
this.navCtrl.setRoot(LoginPage);
}
}
样式 src/pages/home/home.scss
.ios, .md {
home-page {
ion-content {
background-color: map-get($colors, secondary);
}
}
}
网友评论