如何 return 来自路由器事件订阅的路由守卫值
How to return value for route guard from router event subscription
我正在尝试实现基于用户权限的安全路由。没有特定权限的用户无法访问该路由。这就是为什么我在路由中传递正确的名称(惰性模块路由)。但是,我发现获取惰性路由数据有点复杂。我必须订阅路由器事件。但是,在订阅之后,我找不到 return false 或 canactivate true 的方法。
这是我的 canActivate 代码:
canActivate() {
this.router.events
.pipe(
filter((event) => event instanceof NavigationEnd),
map(() => this.activatedRoute),
map((route) => {
while (route.firstChild) {
route = route.firstChild;
}
return route;
}),
mergeMap((route) => route.data))
.subscribe((event) => {
const right = event.right; // getting the right name from the route data.
const rights = this.localStorageService.getLocalStorageItem('rights');
if (right) {
if (rights.includes(right)) {
// I need to return true from here
} else {
// I need to return false from here
}
}
});
}
而且,这是我的路线代码:
const routes: Routes = [{ path: ':id', component: ProfileComponent,
data: { right: 'VIEW_PROFILE' }, canActivate: [RightRouteGuardService]}];
一个Angular路卫可以returnObservable<boolean> | Promise<boolean> | boolean
。我想你想要 return 一个布尔值,但如果在这种情况下我是你,我会 return Observable<boolean>
.
试试这个:
canActivate(): Observable<boolean> {
return this.router.events
.pipe(
filter((event) => !!event), // !! add this filter !!
filter((event) => event instanceof NavigationEnd),
map(() => this.activatedRoute),
map((route) => {
while (route.firstChild) {
route = route.firstChild;
}
return route;
}),
mergeMap((route) => route.data),
// map will return true false for us
map(event => {
const right = event.right; // getting the right name from the route data.
const rights = this.localStorageService.getLocalStorageItem('rights');
if (right) {
if (rights.includes(right)) {
return true;
} else {
return false;
}
}
}),
);
}
您不再需要订阅,只需从这个 observable 发出的第一个发射就会 return 为您判断真假。
=========================编辑=================== =======
不要注入路由器并监听事件,因为路由器还没有完成导航,你的 filter
或 NavigationEnd
将不允许它继续进行,因为当时没有事件.
我已经解决了这个问题:
import { Injectable } from "@angular/core";
import {
ActivatedRouteSnapshot,
CanActivate,
RouterStateSnapshot
} from "@angular/router";
@Injectable({
providedIn: "root"
})
export class RightRouteGuardService implements CanActivate {
constructor() {}
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean{
let right = route.data.right;
console.log({ right });
const rights = ['VIEW_STUDENT'];
if (rights.includes(right)) {
return true;
} else {
return false;
}
}
}
canActivate
方法有两个属性,您可以使用这些属性读取相关路由的数据 属性。
我受到了启发post。
我正在尝试实现基于用户权限的安全路由。没有特定权限的用户无法访问该路由。这就是为什么我在路由中传递正确的名称(惰性模块路由)。但是,我发现获取惰性路由数据有点复杂。我必须订阅路由器事件。但是,在订阅之后,我找不到 return false 或 canactivate true 的方法。
这是我的 canActivate 代码:
canActivate() {
this.router.events
.pipe(
filter((event) => event instanceof NavigationEnd),
map(() => this.activatedRoute),
map((route) => {
while (route.firstChild) {
route = route.firstChild;
}
return route;
}),
mergeMap((route) => route.data))
.subscribe((event) => {
const right = event.right; // getting the right name from the route data.
const rights = this.localStorageService.getLocalStorageItem('rights');
if (right) {
if (rights.includes(right)) {
// I need to return true from here
} else {
// I need to return false from here
}
}
});
}
而且,这是我的路线代码:
const routes: Routes = [{ path: ':id', component: ProfileComponent,
data: { right: 'VIEW_PROFILE' }, canActivate: [RightRouteGuardService]}];
一个Angular路卫可以returnObservable<boolean> | Promise<boolean> | boolean
。我想你想要 return 一个布尔值,但如果在这种情况下我是你,我会 return Observable<boolean>
.
试试这个:
canActivate(): Observable<boolean> {
return this.router.events
.pipe(
filter((event) => !!event), // !! add this filter !!
filter((event) => event instanceof NavigationEnd),
map(() => this.activatedRoute),
map((route) => {
while (route.firstChild) {
route = route.firstChild;
}
return route;
}),
mergeMap((route) => route.data),
// map will return true false for us
map(event => {
const right = event.right; // getting the right name from the route data.
const rights = this.localStorageService.getLocalStorageItem('rights');
if (right) {
if (rights.includes(right)) {
return true;
} else {
return false;
}
}
}),
);
}
您不再需要订阅,只需从这个 observable 发出的第一个发射就会 return 为您判断真假。
=========================编辑=================== =======
不要注入路由器并监听事件,因为路由器还没有完成导航,你的 filter
或 NavigationEnd
将不允许它继续进行,因为当时没有事件.
我已经解决了这个问题:
import { Injectable } from "@angular/core";
import {
ActivatedRouteSnapshot,
CanActivate,
RouterStateSnapshot
} from "@angular/router";
@Injectable({
providedIn: "root"
})
export class RightRouteGuardService implements CanActivate {
constructor() {}
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean{
let right = route.data.right;
console.log({ right });
const rights = ['VIEW_STUDENT'];
if (rights.includes(right)) {
return true;
} else {
return false;
}
}
}
canActivate
方法有两个属性,您可以使用这些属性读取相关路由的数据 属性。
我受到了启发post。