Angular Guard不能与rxjs过滤器一起工作



我试图在我的应用程序中使用RouteGuard来防止未经授权的用户访问它。我在Guard中的can激活方法是这样的:

canActivate(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean | UrlTree> {
return this.statusService.appStatus.pipe(filter(status=>{
return status.selectedAgency!=null;
}),map(status=>{
console.log(status)
if(status.selectedAgency.allowPreEdit){
return true;
}
else{
return false;
}
}))
}

我试图从appStatus可观察对象中过滤默认值,因为它对于selectedAgency为空。之后,代理通过changeSelectedAgency方法从主组件初始化。问题是,它不工作-如果我使用过滤器方法,警卫只是接收到什么-甚至console.log in映射方法不发生。你知道我做错了什么吗?为什么不等待结果呢?如果代理不发生,我将在一个空白的屏幕上,控制台没有任何错误。警卫一定有问题——它不让机构启动,但我不知道为什么。任何想法。StatusService看起来像这样:

export class StatusService {
private statusSubj= new BehaviorSubject<AppStatus>({selectedMonth:new Date(new Date().getFullYear(),new Date().getMonth()),selectedAgency:null});

get appStatus(){
return this.statusSubj.asObservable();
}
changeSelectedAgency(selectedAgency:Agency){
console.log("changeagency");
this.appStatus.pipe(take(1)).subscribe(currentStatus=>{
this.statusSubj.next({...currentStatus,selectedAgency:selectedAgency})
})
}
...
}

export class HomeComponent{
user$:Observable<User>;
agencies:Agency[]=[];
selectedAgency:Agency=null;
commonLoaded=false;
constructor(private breakpointObserver: BreakpointObserver, private userService:UserService, private planService:PlanService, private statusService:StatusService, private commonService:CommonService) {
this.user$=this.userService.currentUser;
forkJoin([this.planService.getAgencies(new Date()),this.commonService.loadTypes()]).subscribe(data=>{
this.initAgencies(data[0]);
console.log(data);
this.commonLoaded=true;
})
}
private initAgencies(agList:Agency[]){
this.agencies=agList;
console.log("init");
this.statusService.changeSelectedAgency(agList[0]);
this.selectedAgency=agList[0];
}

home component html:

<ng-container *ngIf="commonLoaded">
...
<div class="controls-toolbar" *ngIf="agencies.length>0" fxLayoutGap="30px" fxLayoutAlign="left center">
<app-monthpicker></app-monthpicker>
<mat-form-field appearance="fill" class="no-padding no-underline">
<mat-label>Vybraná činnost</mat-label>
<mat-select [(ngModel)]="selectedAgency" (ngModelChange)="changeAgency($event)" [compareWith]="compareAgencies">
<mat-option [value]="agency"  *ngFor="let agency of agencies">Činnost č. {{agency.agNum}}</mat-option>
</mat-select>
</mat-form-field>
<div class="workplace-info" fxLayout fxLayoutAlign="center center" fxLayoutGap="10px"><mat-icon>home</mat-icon><p>{{selectedAgency.wpDesc}}</p></div>
</div>
<div class="content-container" *ngIf="selectedAgency">
<router-outlet></router-outlet>
</div>
</mat-sidenav-content>
</mat-sidenav-container>
</ng-container>

最后是路由:

const routes: Routes = [
{path:"",component:HomeComponent, canActivate:[AuthGuard],
children:[
{path:'',redirectTo:"timesheet",pathMatch:"full"},
{path:'timesheet',component:TimesheetComponent},
...
{path:"shiftRecords",component:ShiftRecordsComponent, canActivate:[PreEditGuard]},
{path:'passchange',component:PassChangeComponent}
]},
{path:'login',component:LoginComponent},
{path:"**",redirectTo:''}

BehaviorSubject中的selectedAgency:null是这里的问题。

因此,filter给您一个空的可观察对象,因此map不会运行。这将导致canActivate返回一个带有假值的可观察对象,因此路由被阻止,HomeComponent没有初始化,因此,构造函数不会运行,initAgencies也不会被调用。

所以,这是一种死锁的情况,canActivate取决于组件初始化(调用initAgencies并设置selectedAgency)但是组件初始化依赖于canActivate(返回true,以便路由和初始化可以进行)。

因此,您可以为selectedAgency提供一些适当的默认值或以其他方式调整您的逻辑。

相关内容

  • 没有找到相关文章

最新更新