我正在开发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;
}
答案 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]
},
.....