我有单身人士服务:
export class CarService {
public currentCar: BehaviorSubject<Car> = new BehaviorSubject(null);
constructor(private jsonApiService: JsonApiService) {
this.jsonApiService.get(`.../activeCar`);
.subscribe(data => {
if(data) {
this.setActiveCar(data);
}
})
}
}
public setActiveCar(activeCar: Car): void {
this.currentBrokerageAccount.next(activeCar);
}
}
然后,我在守卫中使用currentCar
:
canActivateChild(childRoute: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
if (!this.canActivate()) {
return false;
}
if (!this.carService.currentCar.getValue() && state.url !== '/settings') {
this.router.navigate(['/settings']);
}
return true;
}
警卫检查当前车辆,如果有数据则允许打开页面,否则重定向到用户必须选择车辆的设置页面。所以,问题是当我在应用程序中使用菜单然后一切正常,但是当我第一次打开页面(或F5)时,我总是被重定向到设置页面。我理解原因:它是因为carService
尚未从服务器获得活动汽车而且currentCar
为空。如何妥善解决?
PS。流程如下:验证后,如果选择了汽车,用户将看到应用程序中的所有功能。但是,如果未选择汽车,则只有一个网址可用,而且它是settings
。因此,如果未选择汽车,我会将用户重定向到设置页面。
答案 0 :(得分:2)
您正在请求价值的行为主体可能仍在评估来自服务器的所选汽车。您可以使用获取值然后完成的AsyncSubject,而不是&#34;请求&#34;来自服务的当前价值,您应该订阅主题并让他将价值推给您。
//in your service
currentCar$ : AsyncSubject<Car> = new AsyncSubject();
this.jsonApiService.get(`.../activeCar`).subscribe(
(car) => {
currentCar$.next(car);
currentCar$.complete(car);
}
);
//in your guard
//instead of getValue() subscribe to the AsyncSubject
//you should probably handle the "null" case too
this.carService.currentCar$.subscribe(
(car) => {
if ( !car && state.url !== '/settings' ){
this.router.navigate(['/settings']);
}
}
);
订阅将在AsyncSubject完成之前收到它发出的值。
答案 1 :(得分:0)
尝试这种方法
export class CarService {
private data: any;
constructor(private jsonApiService: JsonApiService) {
}
getCar(): Observable<any> {
return this.jsonApiService.get('url')
.map((response: Response) => {
this.data = response.json().data;
return this.data;
}
);
}
hasCarData() {
return data ? true : false;
}
}
public setActiveCar(activeCar: Car): void {
this.currentBrokerageAccount.next(activeCar);
}
}
canActivateChild(childRoute: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
if (!this.canActivate()) {
return false;
}
if(state.url !== '/settings') {
this.carService.getCar()
.subscribe((data: any) => {
if (!this.carService.hasCarData()) {
this.router.navigate(['/settings']);
} else {
return true;
}
});
} else {
return true;
}
}