【发布时间】:2021-03-02 13:25:46
【问题描述】:
上下文:我在我的 Angular 应用程序上创建了一个路由保护。当守卫在该路线上处于活动状态时,它会激活进行检查的守卫。在检查中,它调用一个服务来获取一个值。然后使用该值映射真/假。如果为真,它会直接导航到路线,如果为假,它会显示一个模态。这两种结果都与我面临的问题无关。
问题:在我存在模拟数据的测试环境中,一切都按预期工作。检查运行,获取服务和价值。然后它根据该值返回真/假并调用相关逻辑。在使用真实服务的开发环境中,该值总是返回 undefined,因此总是触发 false。这只发生在第一个实例上。我怀疑这是服务的延迟,并且在服务返回之前运行了真/假逻辑。因此,我在我的模拟服务中添加了延迟,它复制了问题。
尝试过的修复:我尝试在方法运行真/假逻辑之前将.pipe(delay) 添加到该方法中。我也尝试过从构造函数调用服务以提前调用它。
routeGuard.guard.ts
import { catchError, map } from 'rxjs/operators';
import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot } from '@angular/router';
import { Observable, of } from 'rxjs';
import { idService } from '../../idService.service';
@Injectable({
providedIn: 'root'
})
export class UnauthorisedReportGuard implements CanActivate {
constructor(private idService: idService) {}
isIdValid;
id;
validateId(queryParamsId): Observable<boolean> {
this.idService.getId(queryParamsId).subscribe(selectedId => {
this.id = selectedId;
this.isIdValid = this.id.toLowerCase();
});
return of(this.validateIdBool());
}
validateIdBool(): boolean {
if (this.isIdValid === 'validId') {
return true;
}
return false;
}
canActivate(route: ActivatedRouteSnapshot): Observable<boolean> {
const queryParamsId = route.queryParams.id;
return this.validateId(queryParamsId).pipe( //tried adding a delay here
map(e => {
// e returns false first time - this.isIdValid is undefined due to delay in getting service
if (e) {
return true;
} else {
//logic here if false
}
}),
catchError(() => {
return of(false);
})
);
}
}
代码解释: canActivate 已实现,并使用ActivatedRouteSnapshot 从queryParam 中获取id。然后将其传递给validateId(queryParamsId) 方法以调用服务。一旦找到该值,它就会运行另一个方法validateIdBool(): boolean,以根据服务调用返回的值返回真/假。然后将 True 或 flase 返回到 canActivate,它返回 this.validateId(queryParamsId).pipe(map(e =>... 并映射到 e。
【问题讨论】:
-
这可能不起作用,因为您的
return of(this.validateIdBool())将始终将this.isIdValid作为undefined,考虑到订阅是您开发环境中的httpRequest。我建议你使用 RxJs 运算符之类的,我猜它的 switchMap。
标签: angular typescript rxjs angular-ui-router