【问题标题】:Angular2 conditional routingAngular2条件路由
【发布时间】:2016-01-07 16:28:12
【问题描述】:

这可能是一个基本问题,但在 Angular2 中有没有办法进行条件路由?或者,有人会在路由器之外这样做吗?

我知道 ui-router 有能力做到这一点,但我在 Angular2s 路由器中没有看到类似的东西

【问题讨论】:

    标签: angular router


    【解决方案1】:

    如前所述,Angular Route Guards 是实现条件路由的好方法。由于 Angular 教程在这个主题上有点罗嗦,这里是一个简短的总结,如何通过一个例子来使用它们。

    1.有几种类型的警卫。如果您需要if (loggedIn) {go to "/dashboard"} else { go to "/login"} 的逻辑,那么您正在寻找的是CanActivate-Guard。 CanActivate 可以读作“如果所有条件 Y 都满足,则可以激活新路由 X”。您还可以定义重定向等副作用。如果这不符合您的逻辑,请查看 Angular 教程页面以查看其他防护类型。

    2.创建auth-guard.service.ts

    3. 使用以下代码填充auth-guard.service.ts

    import { Injectable } from '@angular/core';
    import {CanActivate, Router, RouterStateSnapshot, ActivatedRouteSnapshot} from '@angular/router';
    
    @Injectable()
    export class AuthGuardService implements CanActivate {
    
      constructor(
        private router: Router
      ) {}
    
      canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
        const isLoggedIn = false; // ... your login logic here
        if (isLoggedIn) {
          return true;
        } else {
          this.router.navigate(['/login']);
          return false;
        }
      }
    
    }
    

    4. 在你的路由模块中注册 auth-guard.service.ts。此外,将键值对 canActivate:[AuthGuardService] 添加到您要保护的所有路由中。它应该看起来像这样:

    const appRoutes: Routes = [
      { path: '', component: LandingComponent},
      { path: 'login', component: LoginComponent},
      { path: 'signup', component: SignUpComponent},
      { path: 'home', component: HomeComponent, canActivate: [AuthGuardService]},
      { path: 'admin', component: AdminComponent, canActivate: [AuthGuardService]},
      { path: '**', component: PageNotFoundComponent }
    ];
    
    @NgModule({
      imports: [
        RouterModule.forRoot(appRoutes)
      ],
      exports: [
        RouterModule
      ],
      providers: [
        AuthGuardService
      ]
    })
    export class AppRoutingModule { }
    

    这应该让你开始。

    这是一个简约的演示:https://stackblitz.com/edit/angular-conditional-routing

    【讨论】:

    • 不错的答案,如果我们在 url 中使用 #,你知道这是否正确吗? this.router.navigate(['#foo']);
    【解决方案2】:

    更新

    在新的路由器守卫可以代替 https://angular.io/guide/router#milestone-5-route-guards

    原版(用于早已不复存在的路由器)

    实现CanActivate 生命周期钩子,如下所示Life cycle hooks in Angular2 router,如果您想阻止导航,则返回 false。 另见https://angular.io/docs/ts/latest/api/router/CanActivate-var.html

    【讨论】:

    • 我想看一个简洁的例子。我有一个Router出口的扩展,你可以在路由之前捕获路由,我在RouteDefinitions中添加了一定的用户权限,所以我可以检查用户是否被允许。但是我有一个子路由,我想对管理员有所不同(查看所有用户而不是个人资料)。我想我现在需要在默认页面中定义特定的逻辑,但这不是我真正想要的。
    【解决方案3】:

    如果你需要渲染一个特定的组件而不是重定向到它,你可以这样做:

    const appRoutes: Routes = [
      {
        path: '' ,
        component: (() => {
          return SessionService.isAnonymous() ? LoginComponent : DashboardComponent;
        })()
      } 
    ]
    

    我将此示例用于登录页面,之前未登录的用户将看到登录页面或仪表板仪表板。

    更新 此代码将在开发环境中运行,但不会构建,您将收到此错误:

    “AppRoutingModule”模板编译期间出现错误 'ɵ0' 中的装饰器不支持函数表达式 'ɵ0' 包含 src/app/app.routing-module.ts(14,25) 处的错误 考虑将函数表达式更改为导出函数。

    为了修复它,我创建了一个单独的模块,如下所示

    import {LandingPageComponent} from '../landing-page/landing-page.component';
    import {DashboardComponent} from "../dashboard/dashboard.component";
    import {SessionService} from "../core/services/session.service";
    
    const exportedComponent = SessionService.isAnonymous() ? LandingPageComponent : DashboardComponent;
    
    export default exportedComponent;
    

    然后你只需要导入那个“工厂”提供的模块

    import LandingPageComponent from './factories/landing-factory.component';
    const appRoutes: Routes = [
      {
        path: '' ,
        component: LandingPageComponent
      },
    ]
    

    【讨论】:

    • 我喜欢这个主意。但在这种情况下,每次会话服务都必须重新实例化。一个人如何能够同时使用服务并保持状态?因为,我需要回复帮助我切换黑白组件的历史数据。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多