Angular 5 RxJS并重定向到仪表板页面而不首先加载主页面

时间:2018-05-04 11:10:57

标签: angular redirect routing rxjs observable

我在我的应用中使用Firebase系统作为API(身份验证,数据库,存储等)

我创建了主页面(localhost:4200),用户未登录时加载,以及登录用户的仪表板(localhost:4200 /仪表板)。

在我的 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

请帮助我做我能做的事情,首先检查用户是否已登录,然后重定向到仪表板而不首先加载主页。我不知道要解决这个问题,因为我只是学习角度和RxJS。

提前谢谢。

1 个答案:

答案 0 :(得分:0)

你似乎对RxJs和角度卫兵有些混淆

<强>问题 第一个问题在于以下代码。

return this.firebaseAuth.authState
  .map(authState => !!authState)
  .do(angularFireAuth => !angularFireAuth ? this.router.navigate(['/']) : true);

这里Map运算符返回一个布尔值。如果!! authState为true,则允许路由导航到DashboardPageComponent,否则没有。

Do Operator的使用是执行副操作/副作用。 Do运算符不会转换值(换句话说,不会影响流)。在这里,do操作员导航到&#39; /&#39;如果angularFireAuth为false,则路由为false。这里!angularFireAuth ? this.router.navigate(['/']) : true三元运算符是无用的。第二个表达没有任何作用。

第二个问题在于app.component.ts中的以下代码。没有必要写这个。

firebaseAuth.authState.subscribe((firebaseUser) => {
  if (firebaseUser != null) {
    this.firebaseUser = firebaseUser;
    this.router.navigate(['dashboard']);
  }
});

<强>解决方案

制造两名警卫。 component: DashboardPageComponent的一个LoggedInGuard  和component: MainPageComponent的另一个NotLoggedInGuard。或者任意你喜欢的名字。

LoggedInGuard

return this.firebaseAuth.authState
   .map(authState => !!authState);

NotLoggedInGuard

return this.firebaseAuth.authState
   .map(authState => !authState);

将上面的代码写在各自的canActivate()函数中,并像以前一样将它们添加到appRoutes中。