angular - Angular 5 RxJS 并重定向到仪表板页面而不首先加载主页
问题描述
我在我的应用程序中使用 Firebase 系统作为 API(身份验证、数据库、存储等)
我创建了主页(localhost:4200),当用户未登录时加载,仪表板(localhost:4200/dashboard)用于登录用户。
在我的app.component.ts构造函数中,我编写了代码:
constructor(private authorizationService: AuthorizationService,
private router: Router,
private firebaseAuth: AngularFireAuth,
private firebaseDatabase: AngularFireDatabase,
private firebaseStorage: AngularFireStorage) {
firebaseAuth.authState.subscribe((firebaseUser) => {
if (firebaseUser != null) {
this.firebaseUser = firebaseUser;
this.router.navigate(['dashboard']);
}
});
}
并在app.component.html
<router-outlet></router-outlet>
app.routing.module.ts:
import {NgModule} from '@angular/core';
import {AuthorizationService} from './services/authorization.service';
import {RouterModule, Routes} from '@angular/router';
import {DashboardPageComponent} from './private/dashboard-page/dashboard-page.component';
import {CanActivateAuthGuard} from './can-activate-auth-guard';
import {LoginPageComponent} from './public/login-page/login-page.component';
import {MainPageComponent} from './public/main-page/main-page.component';
import {RegisterPageComponent} from './public/register-page/register-page.component';
import {ContactPageComponent} from './public/contact-page/contact-page.component';
const appRoutes: Routes = [
{path: '', component: MainPageComponent, pathMatch: 'full'},
{path: 'login', component: LoginPageComponent},
{path: 'register', component: RegisterPageComponent},
{path: 'contact', component: ContactPageComponent},
{path: 'dashboard', component: DashboardPageComponent, canActivate: [CanActivateAuthGuard]}
];
@NgModule({
imports: [
RouterModule.forRoot(appRoutes)
],
providers: [
AuthorizationService
],
exports: [
RouterModule
]
})
export class AppRoutingModule {
}
可以激活-auth-guard.ts:
import {Injectable} from '@angular/core';
import {CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router} from '@angular/router';
import {Observable} from 'rxjs/Observable';
import {AngularFireAuth} from 'angularfire2/auth';
@Injectable()
export class CanActivateAuthGuard implements CanActivate {
constructor(private router: Router,
private firebaseAuth: AngularFireAuth) {
}
canActivate(route: ActivatedRouteSnapshot): Observable<boolean> | Promise<boolean> | boolean {
return this.firebaseAuth.authState
.map(authState => !!authState)
.do(angularFireAuth => !angularFireAuth ? this.router.navigate(['/']) : true);
}
}
但是在完成订阅方法之前,主页会先加载,然后再重定向到/dashboard。
我在记录问题时粘贴了视频: https ://drive.google.com/open?id=1VwgGynxUFPdcpLPkMVopncLEQP-LpasY
请帮助我我能做什么,首先检查用户是否已登录,然后在不首先加载主页的情况下重定向到仪表板。我不知道如何解决这个问题,因为我只是在学习 angular 和 RxJS。
先感谢您。
解决方案
你似乎对 RxJs 和 angular Guards 有一些困惑
问题 第一个问题在于以下代码。
return this.firebaseAuth.authState
.map(authState => !!authState)
.do(angularFireAuth => !angularFireAuth ? this.router.navigate(['/']) : true);
这里 Map 运算符返回一个布尔值。如果 !!authState 为真,则它允许路由导航到 DashboardPageComponent,否则什么也不会。
Do Operator 的用途是执行副操作/副作用。Do 运算符不转换值(换句话说,不影响流)。如果 angularFireAuth 为假,则 do 运算符在此处导航到“/”路线,否则什么也没有。在这里!angularFireAuth ? this.router.navigate(['/']) : true
,三元运算符是无用的。第二个表达式什么也不做。
第二个问题在于 app.component.ts 中的以下代码。没有必要写这个。
firebaseAuth.authState.subscribe((firebaseUser) => {
if (firebaseUser != null) {
this.firebaseUser = firebaseUser;
this.router.navigate(['dashboard']);
}
});
解决方案
创建两个守卫。一个 LoggedInGuardcomponent: DashboardPageComponent
用于component: MainPageComponent
. 或者给他们起任何你喜欢的名字。
LoggedInGuard
return this.firebaseAuth.authState
.map(authState => !!authState);
NotLoggedInGuard
return this.firebaseAuth.authState
.map(authState => !authState);
在它们各自的 canActivate() 函数中编写上面的代码,并appRoutes
像以前一样添加它们。
推荐阅读
- html - 我如何创建两个 div 彼此相邻
- assembly - 带有数组的 MIPS while 循环
- html - 链接样式的 CSS 特性
- google-play - Google Play 商店状态 ---> 此项目与您的设备不兼容,该设备应该用于可穿戴设备
- machine-learning - 如何对机器学习的数据进行过采样 - 回归模型(不是分类!)
- python - 使用 librosa 和 Python 提取声音文件特征
- php - CKFinder + Laravel 8 的问题
- sql - 选择重复的付款和发票
- docker - 如何将我的 docker 容器复制到新计算机?
- c# - 断言服务已作为作用域服务注入