一旦用户登录Ionc4应用程序,如何在单击硬件后退按钮时防止用户返回登录页面?

时间:2019-05-06 13:18:56

标签: angular6 router ionic4 back-button

我正在开发Ionic4 App。因此,首先我有一个“欢迎”页面,其中有一个“登录”按钮,单击该按钮可导航到“登录页面”(使用this.navCtrl.navigateRoot('/ login'))。当用户登录时,使用login.ts中的NavController来显示仪表板。

    login() {
        this.loginService.login().subscribe(user => {

            this.navCtrl.navigateRoot('/dashboard');

        });
    }

在仪表板上,我在构造函数中注册了后退按钮:

    this.platform.backButton.subscribe( () => {

            if(this.router.url=='/dashboard')
                this.presentBackButtonAlert();
        }
    );

单击按钮时,将显示一条警报,以确认用户是否要退出应用程序:

     presentBackButtonAlert() {
        this.alertCtrl.presentAlert({
            header: 'Exit?',
            buttons: [
              {
                text: 'No',
                role: 'cancel',
                handler: () => {
                }

              }, {
                text: 'Yes',
                handler: () => {
                    console.log('Confirm Okay');
                    navigator['app'].exitApp();
                }
              }
            ]

        });
     }

问题是当我点击硬件后退按钮时,会显示警报,但“仪表板页面”会导航回到“欢迎页面”。

我希望当我登录后(在“仪表板页面”上)并点击“后退”按钮时,仅出现警报而无需导航。

这是我的AuthGuard:

    import { Injectable } from '@angular/core';
    import {AuthService} from '../authentication/auth.service';
    import {CanActivate} from '@angular/router';

    @Injectable({
      providedIn: 'root'
    })
    export class AuthGuardService implements CanActivate{

        constructor(private authService: AuthService) { }

        canActivate(): boolean {
            return this.authService.isAuthenticated();
        }

  }

这就是我在路由器模块上使用它的方式:

    {path: 'login', loadChildren: './pages/Auth/login/login.module#LoginPageModule', pathMatch: 'full'},
    {path: 'dashboard', loadChildren: './pages/company/dashboard/dashboard.module#DashboardPageModule', canActivate: [AuthGuardService]},

我的authState位于AuthService中,它看起来像这样:

     public authState = new BehaviorSubject(false);
     public isAuthenticated() {
        return this.authState.value;
     }

3 个答案:

答案 0 :(得分:0)

第一个是仅在Guard中返回布尔值是不够的。如果还没有满足守卫的条件,还应该告诉您要转到哪个页面 所以你可以激活方法

import { Injectable } from '@angular/core';
import {AuthService} from '../authentication/auth.service';
import {CanActivate} from '@angular/router';
import { Router, ActivatedRouteSnapshot } from '@angular/router';

@Injectable({
  providedIn: 'root'
})
export class AuthGuardService implements CanActivate{

    constructor(private router: Router, private authService: AuthService) { }

    canActivate(): boolean {
        if(this.authService.isAuthenticated()){
            this.router.navigate(['/whateverpage'])
            return false;
        }
        return true;
    }

}

您还应该将gaurd添加到您将要转到的页面。由于您要在用户登录后阻止访问登录页面,因此应将防护措施添加到登录页面

 {path: 'login', loadChildren: './pages/Auth/login/login.module#LoginPageModule' canActivate: [AuthGuardService]},
 {path: 'dashboard', loadChildren: './pages/company/dashboard/dashboard.module#DashboardPageModule'},

答案 1 :(得分:0)

对于Ionic4,我尝试了这种方法,对我来说效果很好。

登录页面后的

返回按钮意味着用户要退出应用程序或导航到其他路径。

  

进入视图时,我正在订阅该变量,离开视图时,则取消订阅。这样后退按钮上的退出应用将仅针对该特定页面(例如仪表板页面)执行。

constructor(private platform: Platform){}
backButtonSubscription;
ionViewWillEnter() {
  this.backButtonSubscription = this.platform.backButton.subscribe(async () => {
  navigator['app'].exitApp();
  // edit your code here
  // either you exit or navigate to the desired path
  });
 }
}
ionViewDidLeave() {
 this.backButtonSubscription.unsubscribe();
}

答案 2 :(得分:0)

感谢您的问题和答案,它们以正确的方式指导了我,因为我面临着类似的挑战,就我而言,我对Guard类的canActivate()方法做了如下修改,然后添加了此canActivate仅可对app-routing.module.ts上的auth页面进行配置(其余页面使用canLoad代替):

  canLoad(
    route: Route,
    segments: UrlSegment[]): Observable<boolean> | Promise<boolean> | boolean {

    return this.authService.UserIsAuthenticated.pipe(
      take(1),
      switchMap(isAuthenticated => {
        if (!isAuthenticated) {
          return this.authService.autoLogin();
        } else {
          return of(isAuthenticated);
        }
      }),
      tap(isAuthenticated => {
        if (!isAuthenticated) {
          this.router.navigateByUrl('/auth');
        }
      }));
  }

  canActivate(
    route: import("@angular/router").ActivatedRouteSnapshot,
    state: import("@angular/router").RouterStateSnapshot): boolean | import("@angular/router").UrlTree | Observable<boolean |
      import("@angular/router").UrlTree> | Promise<boolean | import("@angular/router").UrlTree> {
    return this.authService.UserIsAuthenticated.pipe(
      take(1),
      switchMap(isAuthenticated => {
        if (!isAuthenticated) {
          return this.authService.autoLogin();
        } else {
          return of(isAuthenticated);
        }
      }),
      map(isAuthenticated => {
        if (!isAuthenticated) {
          return true;
        } else {
          this.router.navigateByUrl('/dashboard');
          return false;
        }
      }));
  }

因此,在路由配置中,我仅将canActivate用于身份验证页面...

const routes: Routes = [
  {
    path: '', redirectTo: 'auth', pathMatch: 'full',
    canActivate: [AuthGuard]
  },
  {
    path: 'auth',
    loadChildren: () => import('./auth/auth.module').then(m => m.AuthPageModule),
    canActivate: [AuthGuard]
  },
  {
    path: 'products',
    children: [
      {
        path: '',
        loadChildren: './products/products.module#ProductsPageModule',
        canLoad: [AuthGuard]
      },
      {
        path: 'new',
        loadChildren: './products/new-product/new-product.module#NewProductPageModule',
        canLoad: [AuthGuard]
      },
      .....