如何根据 Angular 2 中的条件重定向到某个路由。

Posted

技术标签:

【中文标题】如何根据 Angular 2 中的条件重定向到某个路由。【英文标题】:How to Redirect to a certain route based on condition in Angular 2. 【发布时间】:2017-04-17 10:44:25 【问题描述】:

我正在创建一个 angular2-meteor 应用程序。

export const routes: Route[] = [
    path: '',
    redirectTo: "login",
    pathMatch: "full"
, 

    path: 'login',
    component: LoginComponent
, 

    path: 'csvtemplate',
    component: TemplateComponent,
    canActivate: ['canActivateForLoggedIn'],
    children: [
        path: '',
        redirectTo: 'dashboard' <----how to add condition for multiple path
    , 
    
        path:'dashboard',
        component: DashboardComponent
    ,
    
        path: 'csvtimeline/:month/:year',
        component: CsvTimelineComponent
    , 
        path: 'csvjson',
        component: CsvJsonComponent
    ]
];

当我使用 LoginComponent 登录我的应用程序时,它将转到具有三个子组件的 TemplateComponent

仪表板 csv 时间线 csvjson

现在我默认将 redirectTo 设置为我的仪表板组件。但代替此重定向,我想根据登录用户配置文件重定向到 csvjson 组件或 csvtimeline 组件。

假设

如果登录用户是“管理员”,他应该重定向到 -> 仪表板组件

如果登录用户是“访客”,那么他应该被重定向到 -> csvjson 组件

我知道我们可以在仪表板组件的 ngOnInit() 中执行此操作以进行重定向。

if (this.user && this.user.profile.role == 'Guest') 
             this._router.navigate(['csvtemplate/csvjson']);
        

但我正在寻找更好的选择,所以我不必每次都打开仪表板组件,它会直接转到 csvjson 组件。

【问题讨论】:

可以使用警卫吗? 为什么不直接在你的 LoginComponent 上进行重定向? 【参考方案1】:

这是更好的解决方案:根据 Angular 指南保护管理功能使用 CanActivate 挂钩 步骤:

1) 添加 auth-guard.service.ts 文件

import  Injectable      from '@angular/core';
import  CanActivate     from '@angular/router';
import  Router  from '@angular/router';

@Injectable()
export class AuthGuard implements CanActivate 
    canActivate() 
        //Your redirect logic/condition. I use this.

        if (this.user && this.user.profile.role == 'Guest') 
         this.router.navigate(['dashboard']);
        
        console.log('AuthGuard#canActivate called');
        return true;
    
    //Constructor 
    constructor(private router: Router)  

2) 更新路由文件,在我的例子中是 app.module.ts

import  AuthGuard  from './auth-guard.service';
import  AdminComponent  from './admin/admin.component';
@NgModule(
  declarations: [
    AppComponent,
    AdminComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
    HttpModule,

    RouterModule.forRoot([
        
          path: 'admin',
          component: AdminComponent,
          canActivate:[AuthGuard]
        ,
        
        path: '',
        redirectTo: '/dashboard',
        pathMatch: 'full'
       
    ])
  ],
  providers: [AuthGuard],
  bootstrap: [AppComponent]
)
export class AppModule  

**参考** https://angular.io/docs/ts/latest/guide/router.html#!#can-activate-guard

【讨论】:

很好的解决方案,但不准确,在这种情况下,如果用户知道禁止路由的 url 可以说csvtimeline,那么他只需在浏览器中添加 url 就可以去那里。这个逻辑只是根据登录条件重定向到路由器 如果你在 RouterModule 中定义禁止的路径并像这样设置它的 caActivate 属性会怎样.. RouterModule.forRoot([ path: 'csvtimeline', component: AdminComponent, canActivate:[AuthGuard] , . ....每次用户重定向到 csvtimeline 时,都会调用 canActivate 函数,并且您已经编写了一个条件,您可以将用户重定向到您想要的任何页面。 请告诉我应该从canActivate返回什么?【参考方案2】:

在路由模块中,你需要创建局部变量“路由”,检查条件并分配需要路由路径的变量 并将变量分配给路由中的redirectTo

import  NgModule  from '@angular/core';
import  RouterModule, Routes  from '@angular/router';

var route: string = "user";
const role = JSON.parse(localStorage.getItem("currentUser")).roleId;

if (role == "1") 
//superadmin role
 route = "project"
 else 
  //normal user role
  route = "user"

const adminRoutes: Routes = [ 
path: '',
component: AdminComponent,
canActivate: [AuthGuard],
children: [

   path: '', redirectTo: route ,
  
    path: 'project',
    loadChildren: './project-dashboard/project-dashboard.module#ProjectModule'
  , 
    path: 'user',
    loadChildren: './user/user.module#UserModule',
  

【讨论】:

模块初始化后用户登录/注销时会中断 这是完美的答案,因为它很容易解决问题 异步怎么样?即使我是用户,如果我只是将 localstorage roleId 更改为 admin 怎么办?

以上是关于如何根据 Angular 2 中的条件重定向到某个路由。的主要内容,如果未能解决你的问题,请参考以下文章

当所有路由根据条件动态加载时如何重定向到路由?

如何根据 Flutter 中的条件导航到页面

如何根据符合特定条件的国家/地区代码重定向URL

如何将所有路由重定向到nest.js中的index.html(Angular)?

Angular 2:在应用程序启动时重定向到页面

如何将所有 Angular 请求重定向到 Nginx 中的 index.html