界面如下:
一、首先新增5个tab页面标签,其中一个是more组件pages。
html代码如下:
更多
登录 iMoocQA,体验更多功能
已登录
more.ts代码如下:
import { Component } from '@angular/core';
import { IonicPage, NavController, NavParams, ModalController } from 'ionic-angular';
import { LoginPage} from '../login/login';
import { Storage } from '@ionic/storage';
/**
* Generated class for the MorePage page.
*
* See https://ionicframework.com/docs/components/#navigation for more info on
* Ionic pages and navigation.
*/
// @IonicPage()
@Component({
selector: 'page-more',
templateUrl: 'more.html',
})
export class MorePage {
public notlogin:boolean=true;
public logined:boolean=false;
constructor(public navCtrl: NavController,
public navParams: NavParams,
public modalCtrl:ModalController,
private storage: Storage) {
}
ionViewDidLoad() {
//console.log('ionViewDidLoad MorePage');
}
showmodel(){
const modal = this.modalCtrl.create(LoginPage);
modal.present();
}
ionViewDidEnter(){
this.loadUserPage();
}
loadUserPage(){
this.storage.get('UserId').then((val) => {
// console.log('Your age is', val);
if(val!=null){
this.notlogin=false;
this.logined=true;
// alert("已登录");
}else{
this.notlogin=true;
this.logined=false;
// alert("未登录");
}
});
}
}
二、新增登录页面page,loginpage
login.html:
登录
手机号码
密码
login.ts:
import { Component } from '@angular/core';
import { IonicPage, NavController, NavParams,ViewController,LoadingController, ToastController } from 'ionic-angular';
import { BaseUI } from '../../common/baseui';
import { RestProvider} from '../../providers/rest/rest';
import { Storage } from '@ionic/storage';
import { RegisterPage } from '../register/register';
/**
* Generated class for the LoginPage page.
*
* See https://ionicframework.com/docs/components/#navigation for more info on
* Ionic pages and navigation.
*/
// @IonicPage()
@Component({
selector: 'page-login',
templateUrl: 'login.html',
})
export class LoginPage extends BaseUI {
mobile:any;
password:any;
errorMessage:any;
constructor(public navCtrl: NavController,
public navParams: NavParams,
public viewCtrl: ViewController,
public loadingCtrl: LoadingController,
public rest:RestProvider,
public toastCtrl:ToastController,
private storage: Storage) {
super();//调用父类的构造函数 constructor
}
ionViewDidLoad() {
// console.log('ionViewDidLoad LoginPage');
}
login(){
let loading = super.showLoading(this.loadingCtrl,"登录中...")
this.rest.login(this.mobile,this.password)
.subscribe(f=>{
if(f["Status"]=="OK"){
//处理登录成功的页面跳转
//你也可以存储接口返回的 token(用户是否真实 app=>安全协议)
this.storage.set('UserId', f["UserId"]);
loading.dismiss();
this.dismiss();
}else{
loading.dismiss();
super.showToast(this.toastCtrl,f["StatusContent"])
}
},error=>this.errorMessage=error);
}
//关闭当前页面的方法
dismiss(){
this.viewCtrl.dismiss()
}
pushRegisterPage(){
this.navCtrl.push(RegisterPage);
}
}
三、很多人不理解为啥我还有rest和extends BaseUI,其实我仅仅是为了让我的代码复用
rest.ts代码如下:
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { Http,Response} from '@angular/http';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
/*
Generated class for the RestProvider provider.
See https://angular.io/guide/dependency-injection for more info on providers
and Angular DI.
*/
@Injectable()
export class RestProvider {
constructor(public http: Http) {
// console.log('Hello RestProvider Provider');
}
//feed
private apiUrlFeeds = 'https://imoocqa.gugujiankong.com/api/feeds/get';
//account
private apiUrlRegister = 'https://imoocqa.gugujiankong.com/api/account/register';
private apiUrlLogin = 'https://imoocqa.gugujiankong.com/api/account/login';
private apiUrlUserInfo = 'https://imoocqa.gugujiankong.com/api/account/userinfo';
private apiUrlUpdateNickName = 'https://imoocqa.gugujiankong.com/api/account/updatenickname';
private apiGetUserQuestionList = "https://imoocqa.gugujiankong.com/api/account/getuserquestionlist";
//question
private apiUrlQuestionSave = 'https://imoocqa.gugujiankong.com/api/question/save';
private apiUrlQuestionList = 'https://imoocqa.gugujiankong.com/api/question/list?index=1&number=10';
private apiUrlGetQuestion = "https://imoocqa.gugujiankong.com/api/question/get";
private apiUrlGetQuestionWithUser = "https://imoocqa.gugujiankong.com/api/question/getwithuser";
private apiUrlAnswer = "https://imoocqa.gugujiankong.com/api/question/answer";
private apiUrlSaveFavourite = "https://imoocqa.gugujiankong.com/api/question/savefavourite";
//notification
private apiUrlUserNotifications = "https://imoocqa.gugujiankong.com/api/account/usernotifications";
login(mobile,password):Observable{
return this.getUrlReturn(this.apiUrlLogin+"?mobile="+mobile+"&password="+password)
}
// /**
// * 注册请求
// *
// * @param {any} mobile
// * @param {any} nickname
// * @param {any} password
// * @returns {Observable}
// * @memberof RestProvider
// */
register(mobile, nickname, password): Observable {
return this.getUrlReturn(this.apiUrlRegister + "?mobile=" + mobile + "&nickname=" + nickname + "&password=" + password)
}
private getUrlReturn(url:string):Observable{
return this.http.get(url)
.map(this.extractDate)
.catch(this.handleError);
}
//处理接口返回的数据,处理成json格式
private extractDate(res:Response){
let body =res.json();
return JSON.parse(body)|| {};
}
//处理请求中的错误,考虑了各种情况的错误处理并在console.log中显示error
private handleError(error:Response | any){
let errMsg:string;
if(error instanceof Response){
const body =error.json()||'';
const err = body.error || JSON.stringify(body);
errMsg = `${error.status} - ${error.statusText || ''} ${err}`;
}else{
errMsg = error.message?error.message:error.toString()
}
console.error(errMsg);
return Observable.throw(errMsg);
}
}
rest封装了login、register两大函数,分别对应登录和注册;
getUrlReturn获取数据加载;
extractDate处理接口返回的数据,处理成json格式;
handleError处理请求中的错误,考虑了各种情况的错误处理并在console.log中显示error;
baseUI.ts:
import { Loading, LoadingController, ToastController, Toast } from 'ionic-angular';
// /**
// * UI 层的所有公用方法的抽象类
// *
// * @export
// * @abstract
// * @class BaseUI
// */
export abstract class BaseUI {
constructor() { }
// /**
// * 通用的展示 loading 的组件
// *
// * @protected
// * @param {LoadingController} loadingCtrl
// * @param {string} message
// * @returns {Loading}
// * @memberof BaseUI
// */
protected showLoading(loadingCtrl: LoadingController,
message: string): Loading {
let loader = loadingCtrl.create({
content: message,
dismissOnPageChange: true //页面变化的时候自动关闭 loading
});
loader.present();
return loader;
}
// /**
// * 通用的展示 toast 的组件
// *
// * @protected
// * @param {ToastController} toastCtrl
// * @param {string} message
// * @returns {Toast}
// * @memberof BaseUI
// */
protected showToast(toastCtrl: ToastController, message: string): Toast {
let toast = toastCtrl.create({
message: message,
duration: 3000, //默认展示的时长
position: 'bottom'
});
toast.present();
return toast;
}
}
BaseUI中复用了2块,分别是loading和Toast组件;
四、注册页面编写:
register.html代码如下:
用户注册
手机号码
用户昵称
密码
确认密码
register.ts代码如下:
import { Component } from '@angular/core';
import { IonicPage, NavController, NavParams, ViewController,LoadingController,ToastController } from 'ionic-angular';
import { BaseUI } from '../../common/baseui';
import { RestProvider} from '../../providers/rest/rest';
/**
* Generated class for the RegisterPage page.
*
* See https://ionicframework.com/docs/components/#navigation for more info on
* Ionic pages and navigation.
*/
// @IonicPage()
@Component({
selector: 'page-register',
templateUrl: 'register.html',
})
export class RegisterPage extends BaseUI {
mobile:any;
nickname:any;
password:any;
confirmPassword:any;
errorMessage:any;
constructor(public navCtrl: NavController,
public navParams: NavParams,
public viewCtrl: ViewController,
public rest:RestProvider,
public toastCtrl:ToastController,
public loadingCtrl: LoadingController,) {
super();//调用父类的构造函数 constructor
}
ionViewDidLoad() {
console.log('ionViewDidLoad RegisterPage');
}
dismiss(){
this.viewCtrl.dismiss();
}
gotoLogin(){
this.navCtrl.pop();
//返回上一个nav
}
goRegister(){
if(this.password != this.confirmPassword){
super.showToast(this.toastCtrl,"两次输入的密码不匹配!")
}else{
let loading = super.showLoading(this.loadingCtrl,"注册中...")
this.rest.register(this.mobile,this.nickname,this.password)
.subscribe(f=>{
if(f["Status"]=="OK"){
//处理登录成功的页面跳转
//你也可以存储接口返回的 token(用户是否真实 app=>安全协议)
loading.dismiss();
super.showToast(this.toastCtrl,"注册成功。");
this.dismiss();
}else{
loading.dismiss();
super.showToast(this.toastCtrl,f["StatusContent"])
}
},error=>this.errorMessage=error);
}
}
}
注册和登录基本一致,只是在登录成功的时刻,需要将loading组件进行关闭。
感谢谷歌大佬们,发布的ionic3 最新的安装板块,再也不需要了!