如何在Ionic 2+中创建注销功能

时间:2018-07-09 13:37:30

标签: javascript angular ionic-framework logout

我想在Ionic 2+应用程序中创建一个注销按钮。

我的问题是这样

当我单击ProfilePage上的注销按钮时,我将重定向到WelcomePage,然后又有另一个重定向回到ProfilePage(这是注销按钮所在的页面)。

如何阻止第二次重定向?

这是我的html代码:

        </p>
        <a href="#" (click)="logout()" button ion-button block color="danger" icon-start>
            <ion-icon name='log-out'></ion-icon>
            Se déconnecter
        </a>

还有我的JS函数:

    logout(){
      this.navCtrl.push('WelcomePage');
    }

预先感谢您的帮助

3 个答案:

答案 0 :(得分:0)

有关我的代码的更多详细信息:

Profile.ts

import { Component } from '@angular/core';
import { IonicPage, NavController } from 'ionic-angular';
import { User } from './../../models/user';
import { AngularFireAuth } from "angularfire2/auth";
import { AlertController } from 'ionic-angular';
import { WelcomePage } from '../pages';

@IonicPage()
@Component({
    selector: 'page-profile',
    templateUrl: 'profile.html'
})
export class ProfilePage {
    
    user = {} as User;
    
    pageTitle = "Profile";
    disableForm: Boolean = true;
    email: string;
    idUser: string = '';
    
    /**
    * @text to integrate with back API and database
    * NOT FINISHED
    */
    profile = {
        coverImage: 'assets/img/splashbg.png',
        contact: 'Pour exercer les droits utilisateurs, contacter nous via ce formulaire.',
        mentions: 'Lisez les mentions légales en cliquant ici:',
        password: 'Pour modifier votre mot de passe cliquez ci-dessous:',
        logout: 'Se déconnecter, bouton juste en dessous.',
        delete: 'Supprimer définitivement mon compte.'
    };
    
    /**
    * @data userTest to implements with the API
    * NOT FINISHED
    */
    userTest = {
        username: 'romain',
        profileImage: 'assets/img/romain.jpg',
        country: 'France',
        city: 'Paris',
        description: '',
        languages: ['Français', 'Anglais'],
    };
    
    constructor(
        public navCtrl: NavController,
        private aFAuth: AngularFireAuth,
        private alertCtrl: AlertController
    ) {  
        this.aFAuth.authState.subscribe(
            data => {
                this.idUser = data.uid;
                this.email = data.email;
            }
        )
    }
    
    ionViewWillLoad() {
        console.log('profile page loaded');
    } 
    
    
    ionViewDidLoad(){
        this.idUser = this.aFAuth.auth.currentUser.uid;
    }
    
    
    /**
    * Edit user information (Firebase and Database)
    * NOT FINISHED
    * @method edit
    */
    edit(user){
        this.disableForm = !this.disableForm;
        console.log(user);
        // check if entries are empty
        // update entries in firebase 
        // update entries in database
    };
    
    /**
    * Edit password with Firebase API
    * 
    * @method editPassword
    * return nothing but the user get's an email
    */
    editPassword(){
        if(this.email == null) {
            const alert = this.alertCtrl.create({
                title: 'Email vide!',
                subTitle: 'Contacter le support.',
                buttons: ['OK']
            });
            alert.present();
        } else {
            this.aFAuth.auth.sendPasswordResetEmail(this.email);
            const alert = this.alertCtrl.create({
                title: 'Email envoyé!',
                subTitle: 'Un email vous a été envoyé. Veuillez y suivre les instructions.',
                buttons: ['OK']
            });
            alert.present();
        }
    };
    
    /**
    * Delete an user from profile page with Firebase.
    * NOT FINISHED still an console error but the user is deleted
    * @method deleteUser
    */
    deleteUser(){

        var userDelete = this.aFAuth.auth.currentUser;
        
        const deleteConfirm = this.alertCtrl.create({
            title: 'Suppression de compte ?',
            message: 'Cette action va supprimer votre compte ainsi que toutes les données qui y sont relié. Cette action est irrévocable.',
            buttons: [
                {
                    text: 'Non',
                    handler: () => {
                        console.log('Non');
                    }
                },
                {
                    text: 'Ok',               
                    handler: () => {
                        try {
                            userDelete.delete();
                            console.log('deleted');
                            this.navCtrl.push('WelcomePage');
                        } catch(e){
                            this.navCtrl.push('WelcomePage');
                        }
                    }
                }
            ]
        });
        deleteConfirm.present();
    }
    
    
    /**
    * Log out with Firebase Web API signOut method
    * NOT FINISHED error on uid
    * @method logOut
    */
    logout(){
        try {
            this.navCtrl.push('WelcomePage');
            console.log('User logged out 1');
        } catch {
            this.navCtrl.push('WelcomePage');
            console.log('User logged out 2');
        }

        console.log('User logged out 3');
    }
}

Profile.html

<ion-header>
    <ion-navbar color="primary">
        <ion-title>Profil</ion-title>
    </ion-navbar>
</ion-header>

<ion-content parallax-header no-bounce class="bg-modal">
    <div class="header-image">
        <button ion-button (click)="edit(user)" color="secondary" item-end medium>
            <ion-icon name='create'></ion-icon>
        </button>
    </div>
    <div class="main-content" text-wrap text-center>
        <div class="circular"></div>
        <h2>{{userTest.username}}</h2>
        <p class="profile-description">{{userTest.description}}</p>
        <ion-list no-lines>
            <ion-item>
                <ion-icon name="mail" color="primary" item-start></ion-icon>
                <ion-input placeholder="Email" type="email" class="profile-text" id="profile-input" [(ngModel)]="email" [readonly]="disableForm"></ion-input>
            </ion-item>

            <ion-item>
                <ion-icon name="home" color="primary" item-start></ion-icon>
                <ion-input placeholder="City" type="text" class="profile-text" id="profile-input" [(ngModel)]="userTest.city" [readonly]="disableForm"></ion-input>
            </ion-item>
            <ion-item>
                <ion-icon name="home" color="primary" item-start></ion-icon>
                <ion-input placeholder="Country" type="text" class="profile-text" id="profile-input" [(ngModel)]="userTest.country" [readonly]="disableForm"></ion-input>
            </ion-item>
            <ion-item>
                <ion-icon name="chatbubbles" color="primary" item-start></ion-icon>
                <ion-input placeholder="Langues" type="text" class="profile-text" id="profile-input" [(ngModel)]="userTest.languages" [readonly]="disableForm"></ion-input>
            </ion-item>
        </ion-list>
        <hr><hr>
        <p class="profile-text">
            {{profile.password}}
        </p>
        <a href="#" (click)="editPassword(user)" button ion-button block color="primary" icon-start>
            <ion-icon name='finger-print'></ion-icon>
            Mot de passe
        </a>
        <p class="profile-text">
            {{profile.contact}}
        </p>
        <a href="#" button ion-button block color="secondary" icon-start>
            <ion-icon name='contact'></ion-icon>
            Formulaire de contact
        </a>
        <p class="profile-text">
            {{profile.mentions}}    
        </p>
        <a href="#" button ion-button block color="secondary" icon-start>
            <ion-icon name='copy'></ion-icon>
            Lire les mentions légales
        </a>

        <br>
        <hr>
        <p class="profile-text">
            {{profile.logout}}
        </p>
        <a href="#" (click)="logout()" button ion-button block color="danger" icon-start>
            <ion-icon name='log-out'></ion-icon>
            Se déconnecter
        </a>
        
        <br>
        <hr>
        <p class="profile-text">
            {{profile.delete}}
        </p>
        <a href="#" (click)="deleteUser()" button ion-button block color="danger" icon-start>
            <ion-icon name='trash'></ion-icon>
            Supprimer mon compte
        </a>

    </div>
</ion-content>

Welcome.ts

import { Component } from '@angular/core';
import { IonicPage, NavController, ViewController } from 'ionic-angular';

/**
 * The Welcome Page is a splash page that quickly describes the app,
 * and then directs the user to create an account or log in.
 * If you'd like to immediately put the user onto a login/signup page,
 * we recommend not using the Welcome page.
*/
@IonicPage()
@Component({
  selector: 'page-welcome',
  templateUrl: 'welcome.html'
})
export class WelcomePage {

  constructor(
    public navCtrl: NavController,
    public viewCtrl: ViewController,
  ) { }

  ionViewWillEnter(){
    this.viewCtrl.showBackButton(false);
  }

  login() {
    this.navCtrl.push('LoginPage');
  }

  register() {
    this.navCtrl.push('RegisterPage');
  }
}

app.component.ts

import { Component, ViewChild } from '@angular/core';
// import { SplashScreen } from '@ionic-native/splash-screen';
// import { StatusBar } from '@ionic-native/status-bar';
import { TranslateService } from '@ngx-translate/core';
import { Config, Nav, Platform } from 'ionic-angular';

import { WelcomePage, DevPage } from '../pages/pages';

@Component({
    templateUrl: 'app.html'
})
export class MyApp {
  rootPage = DevPage ? DevPage : WelcomePage;

    @ViewChild(Nav) nav: Nav;

  pages: any[] = [
    { title: 'Tutorial', component: 'TutorialPage' },
    { title: 'Welcome', component: 'WelcomePage' },
    { title: 'Tabs', component: 'TabsPage' },
    { title: 'Cards', component: 'CardsPage' },
    { title: 'Content', component: 'ContentPage' },
    { title: 'Login', component: 'LoginPage' },
    { title: 'Master Detail', component: 'ListMasterPage' },
    { title: 'Menu', component: 'MenuPage' },
    { title: 'Messages', component: 'MessagesPage' },
    { title: 'Search', component: 'SearchPage' },
    { title: 'Profile', component: 'ProfilePage' }
  ]

  constructor(
      private translate: TranslateService, 
      platform: Platform, 
      private config: Config, 
    //   private statusBar: StatusBar, 
    //   private splashScreen: SplashScreen
      ) {
    platform.ready().then(() => {
      console.log('dev page : ', DevPage);
      // Okay, so the platform is ready and our plugins are available.
      // Here you can do any higher level native things you might need.
    //   this.statusBar.styleDefault();
    //   this.splashScreen.hide();
    });
    this.initTranslate();
  }

    initTranslate() {
        // Set the default language for translation strings, and the current language.
        this.translate.setDefaultLang('en');
        const browserLang = this.translate.getBrowserLang();

        if (browserLang) {
            if (browserLang === 'zh') {
                const browserCultureLang = this.translate.getBrowserCultureLang();

                if (browserCultureLang.match(/-CN|CHS|Hans/i)) {
                    this.translate.use('zh-cmn-Hans');
                } else if (browserCultureLang.match(/-TW|CHT|Hant/i)) {
                    this.translate.use('zh-cmn-Hant');
                }
            } else {
                this.translate.use(this.translate.getBrowserLang());
            }
        } else {
            this.translate.use('en'); // Set your language here
        }

        this.translate.get(['BACK_BUTTON_TEXT']).subscribe(values => {
            this.config.set('ios', 'backButtonText', values.BACK_BUTTON_TEXT);
        });
    }

    openPage(page) {
        // Reset the content nav to have just this page
        // we wouldn't want the back button to show in this scenario
        this.nav.setRoot(page.component);
    }
}

答案 1 :(得分:0)

因此Ionic正在使用所谓的“导航堆栈”,其中(应该是)有一个根页面,然后其他页面可能是:

  • 替换rootPage或
  • 被推到顶部(=堆叠在顶部)

以离子导航堆叠为例:

enter image description here

因此,您可以替换初始硬币(您的rootPage就是这样的硬币),并且可以从堆栈中推入更多硬币(页面)或弹出它们(删除页面)。

现在提出您的问题-在您的情况下,您似乎没有在其他页面上执行弹出操作/也没有替换rootPage,或者以其他方式正确管理堆栈。 根据您的用户体验,您可能希望使用户返回到其登录时出现的应用程序状态。

通常,如果您的原始(rootPage)是“欢迎页面”,那么您要做的就是使用

返回该页面(rootPage)。

https://ionicframework.com/docs/api/navigation/NavController/#popToRoot

因此,根据您的根页面是什么(不幸的是,您没有提供具有该上下文的代码),您可以:

logout(){
    this.navCtrl.popToRoot();
}

我建议您考虑一下导航堆栈策略,并决定何时分配新的rootPage以及何时进行推送/弹出。

根据我的经验,当我要引导用户浏览的是一个全新的页面/主题/主题时,我通常总是替换rootPage,并且仅在其与rootPage相关的另一个页面/模式时才使用push。

另一种查看方式:您不希望堆栈太大(不断推入新页面),也不希望用户“返回”(弹出)超过2-3层。

答案 2 :(得分:0)

请尝试。

logout(){
     //clear any storage and cached data
    this.app.getRootNav().setRoot(LoginPage);
}