首页 > 解决方案 > 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。

先感谢您。

标签: angularredirectroutingrxjsobservable

解决方案


你似乎对 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像以前一样添加它们。


推荐阅读