1. 程式人生 > >02-ionic編寫登入以及使用者暱稱更改教程

02-ionic編寫登入以及使用者暱稱更改教程

繼續上次的01 ionic教程更新

 

附上原始碼地址:

https://pan.baidu.com/s/1wNHUVe2qcKjwSWv4DTqzIQ

 

 

注意:node.js建議安裝最新版,然後安裝Storage,才可以執行ionic serve

 

在上次的案例程式碼基礎上新增一個pages,name is user.-

user.html原始碼:

<!--
  Generated template for the UserPage page.

  See http://ionicframework.com/docs/components/#navigation for more info on
  Ionic pages and navigation.
-->
<ion-header>

  <ion-navbar>
    <ion-title>個人中心</ion-title>
  </ion-navbar>

</ion-header>


<ion-content>

  <ion-list class="margin_top">
    <button ion-item>
      <ion-avatar item-start>
        <img src="{{headface}}" />
      </ion-avatar>
      <h2>修改頭像</h2>
      <p>檢視個人主頁或剪輯簡介</p>
    </button>

  </ion-list>

  <ion-list>
    <ion-item>
      <ion-label>使用者暱名</ion-label>
      <ion-input type="text" [(ngModel)]="nickname"></ion-input>
    </ion-item>

  </ion-list>
  <div class="mypadding">
    <button ion-button color="primary" block (click)="updatenickname()">儲存</button>
  </div>
  <div class="mypadding">
    <button ion-button color="danger" block (click)="logout()">登出</button>
  </div>
</ion-content>

user.ts:

import { Component } from '@angular/core';
import { IonicPage, NavController, NavParams, ModalController, LoadingController,ToastController,ViewController } from 'ionic-angular';
import { Storage } from '@ionic/storage';
import { BaseUI } from '../../common/baseui';
import { RestProvider } from '../../providers/rest/rest';


/**
 * Generated class for the UserPage page.
 *
 * See https://ionicframework.com/docs/components/#navigation for more info on
 * Ionic pages and navigation.
 */

// @IonicPage()
@Component({
  selector: 'page-user',
  templateUrl: 'user.html',
})
export class UserPage extends BaseUI {
  headface: string = "assets/imgs/mr.jpg";
  nickname: string = "載入中...";
  errorMessage: string;

  constructor(public navCtrl: NavController, public navParams: NavParams,
    public modalCtrl: ModalController,
    public loadingCtrl: LoadingController,
    public rest: RestProvider,
    public toastCtrl : ToastController,
    public viewCtrl: ViewController,
    private storage: Storage) {
    super();
  }

  ionViewDidLoad() {
    this.loadUserPage();
  }

  loadUserPage() {
    this.storage.get('UserId').then((val) => {
      // console.log('Your age is', val);
      if (val != null) {
        //載入使用者資料
        var loading = super.showLoading(this.loadingCtrl, "載入中...");
        this.rest.getUserInfo(val).subscribe(
          userinfo => {
            this.nickname = userinfo["UserNickName"];
            this.headface = userinfo["UserHeadface"] + "?" + (new Date()).valueOf();

            loading.dismiss();

          }, error => this.errorMessage = <any>error);
      }
    });

  }

  updatenickname() {
    this.storage.get('UserId').then((val) => {
      if (val != null) {
        //載入使用者資料
        var loading = super.showLoading(this.loadingCtrl, "修改中...");
        this.rest.updatenickname(val,this.nickname).subscribe(
          f => {
            if(f["Status"]=="OK"){
              // this.nickname = f["UserNickName"];
              // this.headface = f["UserHeadface"] + "?" + (new Date()).valueOf();
  
              loading.dismiss();
              super.showToast(this.toastCtrl,"暱稱修改成功.");
            }else{
              loading.dismiss();
              // super.showToast(this.toastCtrl,"修改失敗");
              //一般錯誤出現在後端了,以防萬一。
              super.showToast(this.toastCtrl,f["StatusContent"]);
            }
          }, error => this.errorMessage = <any>error);
      }
    })
  }

  logout(){
    this.storage.remove("UserId");
    this.viewCtrl.dismiss();
  }

}

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<string[]> {
    return this.getUrlReturn(this.apiUrlLogin + "?mobile=" + mobile + "&password=" + password);

  }
  getUserInfo(userId): Observable<string[]> {
    return this.getUrlReturn(this.apiUrlUserInfo + "?userid=" + userId);
  }

  updatenickname(userId, nickname): Observable<string[]> {
    return this.getUrlReturn(this.apiUrlUpdateNickName + "?userid=" + userId + "&nickname=" + nickname);
  }
  //   /**
  //  * 註冊請求
  //  * 
  //  * @param {any} mobile 
  //  * @param {any} nickname 
  //  * @param {any} password 
  //  * @returns {Observable<string[]>} 
  //  * @memberof RestProvider
  //  */
  register(mobile, nickname, password): Observable<string[]> {
    return this.getUrlReturn(this.apiUrlRegister + "?mobile=" + mobile + "&nickname=" + nickname + "&password=" + password)
  }



  private getUrlReturn(url: string): Observable<string[]> {
    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);
  }

}

值得注意的是之所以要編寫

headface: string = "assets/imgs/mr.jpg";

nickname: string = "載入中...";

是因為我需要將他的預設資料進行載入。rest是複用資料函式專用的ts,更新即可。

 

接下來解決登入過後,登入頁面無法重新整理進入個人中心問題:

 

原來more.ts中負責進入登入頁面的原始碼:

 showmodel() {
    const modal = this.modalCtrl.create(LoginPage); 

    modal.present();
  }

改進如下:

 showmodel() {
    const modal = this.modalCtrl.create(LoginPage);

    //關閉後的回撥
    //因為modal關閉的時候,不會再次觸發父頁面的ionViewDidEnter();
    
    modal.onDidDismiss(()=>{
      this.loadUserPage();
    })

    modal.present();
  }

原理已經在註釋之中,我的loadUserPage()函式程式碼如下:

 loadUserPage() {
    this.storage.get('UserId').then((val) => {
      // console.log('Your age is', val);
      if (val != null) {
        //載入使用者資料
        var loading = super.showLoading(this.loadingCtrl, "載入中...");
        this.rest.getUserInfo(val).subscribe(
          userinfo => {
            this.userinfo = userinfo;
            this.headface = userinfo["UserHeadface"] + "?" + (new Date()).valueOf();
            this.notlogin = false;
            this.logined = true;

            loading.dismiss();

          }
        );

        // this.notlogin = false;
        // this.logined = true;
        // alert("已登入");
      } else {
        this.notlogin = true;
        this.logined = false;
        // alert("未登入");
      }
    });

  }

ionic的tabs api文件中有寫如何返回路由,可是我們這邊用的是model,那麼就只需要按部就班即可,直接使用onDidDismiss方法將我們的函式重新讀取。

 

感謝各位的解讀,望大家收藏。