要在Angular中使用RxJs守卫等待服务的BehaviorSubject有值,可以使用RxJs中的操作符filter
来等待BehaviorSubject的值。
下面是一个示例代码:
首先,创建一个名为AuthGuardService
的守卫服务,并注入一个名为AuthService
的认证服务。
import { Injectable } from '@angular/core';
import { CanActivate, Router } from '@angular/router';
import { AuthService } from './auth.service';
import { BehaviorSubject } from 'rxjs';
import { filter } from 'rxjs/operators';
@Injectable({
providedIn: 'root'
})
export class AuthGuardService implements CanActivate {
constructor(private authService: AuthService, private router: Router) { }
canActivate(): Observable {
return this.authService.isAuthenticated.pipe(
filter(value => value !== null), // 筛选出非空值
map(isAuthenticated => {
if (isAuthenticated) {
return true;
} else {
this.router.navigate(['/login']);
return false;
}
})
);
}
}
然后,在AuthService
中创建一个名为isAuthenticated
的BehaviorSubject,并在登录成功时将其设置为true
。
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class AuthService {
isAuthenticated: BehaviorSubject = new BehaviorSubject(null);
constructor() { }
login() {
// 登录逻辑
// ...
// 登录成功后设置isAuthenticated为true
this.isAuthenticated.next(true);
}
}
最后,在路由模块中使用AuthGuardService
作为守卫。
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { AuthGuardService } from './auth-guard.service';
import { LoginComponent } from './login/login.component';
import { HomeComponent } from './home/home.component';
const routes: Routes = [
{ path: 'login', component: LoginComponent },
{ path: 'home', component: HomeComponent, canActivate: [AuthGuardService] },
{ path: '', redirectTo: '/home', pathMatch: 'full' }
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
这样,当访问需要身份验证的路由时,守卫将等待isAuthenticated
的BehaviorSubject具有非空值,然后根据其值决定是否允许访问路由。如果isAuthenticated
的值为null
,守卫将等待直到值发生变化。如果值为true
,则允许访问路由,否则将重定向到登录页面。