【问题标题】:How to Redirect to a certain route based on condition in Angular 2.如何根据 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 上进行重定向?

标签: angular angular2-routing angular2-meteor


【解决方案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 怎么办?
猜你喜欢
  • 2019-09-21
  • 2017-08-10
  • 1970-01-01
  • 2021-08-10
  • 2016-07-07
  • 2023-04-04
  • 2017-04-24
  • 2021-11-07
相关资源
最近更新 更多