如何在 Angular 中设置用户特定的路由?
How to set user-specific routes in Angular?
我有一个 Angular 6 应用程序,它使用提供商信息来确定应用程序的功能(渠道)。我正在处理用户登录后从服务器接收到的对象,它为我提供了各个频道的布尔值。
providerInfos = {
channels: {
a: true,
b: true,
c: true
}
}
在index.html我有
<base href="/home/">
在我的应用程序中-routing.module我有
const routes: Routes = [
{ path: '', redirectTo: 'a', pathMatch: 'full' }, // Set /a as "start page".
{ path: 'a', component: AComponent, runGuardsAndResolvers: 'always' },
{ path: 'a/:id', component: ADetailsComponent },
{ path: 'b', component: BComponent },
{ path: 'c', component: CComponent }
];
所以当应用程序初始化时,A 被加载(某处。io/home/a)。到目前为止这很好,但由于应用程序的进一步开发,事实证明 A 也不能作为频道提供。这给我带来了一个我还无法解决的问题。我越想越看我的代码,我越觉得我以前的做法基本上是错误的。
在初始化应用程序时,如果 A 不是应用程序功能的一部分,我希望能够将 B 或 C 显示为第一个或唯一的视图(某处。io/home/whatever)。原则上,我想根据通过用户提供者信息为用户定义的功能为应用程序提供路由,至少
path: '', redirectTo: 'whatever', pathMatch: 'full'
如果只给出一个功能。
我可以通过提供者信息自定义功能,以便自定义侧边栏中的菜单,并且如果有人想到在URL 栏。但是我无法相应地调整路线。
你会如何处理这个问题。有这方面的最佳实践吗?
您可以使用路由守卫来实现此功能。路由守卫不仅阻止用户访问路由,它们还允许您通过返回 UrlTree
.
告诉路由器导航到哪里。
给定以下路线:
const routes = [
{ path: '', redirectTo: 'a', pathMatch: 'full' },
{ path: 'a', component: ComponentA, canActivate: [AuthGuard] },
{ path: 'b', component: ComponentB }
];
我可以按如下方式设置我的 AuthGuard
:
@Injectable({
providedIn: 'root'
})
export class AuthGuard implements CanActivate {
constructor(private router: Router, private userService: UserService) {
}
canActivate() : boolean | UrlTree {
const user = this.userService.getCurrentUser();
const userCanAccessA = false; // TODO: implement
if (userCanAccessA) {
return true;
}
// redirect to /b
return this.router.parseUrl('/b');
}
}
我不推荐这个例子作为一个好的实现,我只是在展示路由守卫的能力。您的要求将决定您的路由结构以及重定向逻辑。
让守卫做很多工作很诱人。相反,我会让每个警卫专注于执行特定任务。然后,如果需要,您可以通过组合守卫来编写守卫逻辑。
请注意,在我下面的演示中,组件 A 从未构建,因为 AuthGuard
在路由发生之前阻止访问。
我有一个 Angular 6 应用程序,它使用提供商信息来确定应用程序的功能(渠道)。我正在处理用户登录后从服务器接收到的对象,它为我提供了各个频道的布尔值。
providerInfos = {
channels: {
a: true,
b: true,
c: true
}
}
在index.html我有
<base href="/home/">
在我的应用程序中-routing.module我有
const routes: Routes = [
{ path: '', redirectTo: 'a', pathMatch: 'full' }, // Set /a as "start page".
{ path: 'a', component: AComponent, runGuardsAndResolvers: 'always' },
{ path: 'a/:id', component: ADetailsComponent },
{ path: 'b', component: BComponent },
{ path: 'c', component: CComponent }
];
所以当应用程序初始化时,A 被加载(某处。io/home/a)。到目前为止这很好,但由于应用程序的进一步开发,事实证明 A 也不能作为频道提供。这给我带来了一个我还无法解决的问题。我越想越看我的代码,我越觉得我以前的做法基本上是错误的。
在初始化应用程序时,如果 A 不是应用程序功能的一部分,我希望能够将 B 或 C 显示为第一个或唯一的视图(某处。io/home/whatever)。原则上,我想根据通过用户提供者信息为用户定义的功能为应用程序提供路由,至少
path: '', redirectTo: 'whatever', pathMatch: 'full'
如果只给出一个功能。
我可以通过提供者信息自定义功能,以便自定义侧边栏中的菜单,并且如果有人想到在URL 栏。但是我无法相应地调整路线。
你会如何处理这个问题。有这方面的最佳实践吗?
您可以使用路由守卫来实现此功能。路由守卫不仅阻止用户访问路由,它们还允许您通过返回 UrlTree
.
给定以下路线:
const routes = [
{ path: '', redirectTo: 'a', pathMatch: 'full' },
{ path: 'a', component: ComponentA, canActivate: [AuthGuard] },
{ path: 'b', component: ComponentB }
];
我可以按如下方式设置我的 AuthGuard
:
@Injectable({
providedIn: 'root'
})
export class AuthGuard implements CanActivate {
constructor(private router: Router, private userService: UserService) {
}
canActivate() : boolean | UrlTree {
const user = this.userService.getCurrentUser();
const userCanAccessA = false; // TODO: implement
if (userCanAccessA) {
return true;
}
// redirect to /b
return this.router.parseUrl('/b');
}
}
我不推荐这个例子作为一个好的实现,我只是在展示路由守卫的能力。您的要求将决定您的路由结构以及重定向逻辑。
让守卫做很多工作很诱人。相反,我会让每个警卫专注于执行特定任务。然后,如果需要,您可以通过组合守卫来编写守卫逻辑。
请注意,在我下面的演示中,组件 A 从未构建,因为 AuthGuard
在路由发生之前阻止访问。