简体   繁体   English

将值从 RouterStateSnapshot 传递到 Angular 2 App 中的根路由文件

[英]Passing Value from RouterStateSnapshot to my Root Routing File in Angular 2 App

I am trying to figure out how to pass the value from the RouterStateSnapshot in my auth.guard file to my routing file in my Angular 2 app.我想弄清楚如何将值从 auth.guard 文件中的 RouterStateSnapshot 传递到我的 Angular 2 应用程序中的路由文件。 I want to do this because, rather than loading a hard-coded default component first, I want, after re-login, for the last active component/page to load up.我想这样做是因为,与其先加载硬编码的默认组件,不如在重新登录后加载最后一个活动组件/页面。 I have this value in my canActivate() function in my AuthGuard file, because I can console out it out via RouterStateSnapshot.我在我的 AuthGuard 文件的 canActivate() 函数中有这个值,因为我可以通过 RouterStateSnapshot 控制台输出它。 So now I need to figure out how to pass this value on to my root routing file so it, on login/re-login, that component gets loaded.所以现在我需要弄清楚如何将此值传递给我的根路由文件,以便在登录/重新登录时加载该组件。

This is the canActivate() function in my AuthGuard file:这是我的AuthGuard文件中的canActivate()函数:

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot)
{
    // Get route content id
    let contentId = Object.getPropertyValueAtPath(route, 'data.contentId');

    console.log(state.url);

    // If route does not have session id, don’t load in tab view
    if (!String.isNotNullOrEmpty(contentId))
    {
        console.error(`Route (${route.routeConfig.path}) does not have a content id.`);
        this.router.navigateByUrl(''); // Forward to default page.
        this.router.navigate([state.url]);
        return false;
    }

    if (this.disabled) return true;

    if (sessionStorage.getItem('currentUser'))
    {
        // logged in so return true
        return true;
    }

    // not logged in so redirect to login page with the return url
    this.router.navigate(['/login', {returnUrl: state.url}]);
    return false;
}

Notice that I am doing this within that function: console.log(state.url) .请注意,我在该函数中执行此操作: console.log(state.url) This gives me the correct value.这给了我正确的价值。 Now I need to pass it to my app-routing file.现在我需要将它传递给我的应用程序路由文件。

To clarify, currently, on re-login, the last active component is loaded -- but it displays as a background tab, and the default 'redirect' component is what loads up as the active component (ie, it shows as the active tab).为了澄清,目前,在重新登录时,最后一个活动组件加载-但它显示为背景标签,默认的“重定向”成分是什么负荷高达为活性组分(即,它显示为活动标签)。

A simplified version of the app-routing file looks like this:应用程序路由文件的简化版本如下所示:

import { HomeComponent } ...

export const routes: Routes = [

{ path: 'login', component: LoginComponent },

{ path: 'home', component: HomeComponent },

{ path: 'about', component: AboutComponent },

{ path: '**', redirectTo: 'home' }

];

As you can see above, on initial load I currently redirect the user to the 'home component' by default.正如您在上面看到的,在初始加载时,我目前默认将用户重定向到“home 组件”。 What I'd like to do is re-direct them to the value that is stored in "state.url" from RouterStateSnapshot.我想做的是将它们重定向到 RouterStateSnapshot 中存储在“state.url”中的值。 I'm not clear how to do this, however.但是,我不清楚如何做到这一点。 Any ideas as to how I'd pass that value from my AuthGuard file down to my app-routing file?关于如何将该值从我的 AuthGuard 文件传递​​到我的应用程序路由文件的任何想法? Can I simply inject RouterStateSnapshot into my app-routing file to get that desired value directly?我可以简单地将 RouterStateSnapshot 注入到我的应用程序路由文件中以直接获得所需的值吗? Or can I use "resolve" here along with the path in routing?或者我可以在这里使用“resolve”以及路由中的路径吗? What's the recommended way to handle this kind of scenario?处理这种情况的推荐方法是什么?

I accomplish this by storing the url in a shared service from my AuthGuard我通过将 url 存储在来自我的 AuthGuard 的共享服务中来完成此操作

// auth-guard.ts
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
  let isLoggedIn = this.authService.isUserLoggedIn();

  if(isLoggedIn){
    return true;
  }else{
    this.someService.storeRedirectUrl(state.url);
    this.router.navigateByUrl('/login');
    return false;
  }
}

Then when the user logs in, check if that redirect url was stored and navigate to it然后当用户登录时,检查该重定向 url 是否已存储并导航到它

// login method within login page
login(){
  this.authService.login(email, password).subscribe(
    res => {
      // successful user login, so determine where to route user
      if(this.someService.redirectUrl){
        // redirect url found, navigate to that url
        this.router.navigateByUrl(this.someService.redirectUrl);
      }else{
        // if no redirect url found, navigate to normal landing page
        this.router.navigateByUrl('/home');
      }
  });
}

Routes File路由文件

// routes
export const routes: Routes = [
  {
    path: 'login', 
    component: LoginComponent 
  },
  { 
    path: 'home', 
    component: HomeComponent,
    canActivate: [AuthGuard]
  },
  { 
    path: 'about', 
    component: AboutComponent,
    canActivate: [AuthGuard]
  },
  { 
    path: '**', 
    redirectTo: 'home' 
  }
];

Can I simply inject RouterStateSnapshot into my app-routing file to get that desired value directly?我可以简单地将 RouterStateSnapshot 注入到我的应用程序路由文件中以直接获得所需的值吗?

app-routing is just for mapping routes to components, so there is no injecting the route snapshot into it. app-routing 只是用于将路由映射到组件,因此没有将路由快照注入其中。

Another option you could do is to pass the redirect url as a query parameter of the login page within the auth guard.您可以做的另一个选择是将重定向 url 作为登录页面的查询参数传递给 auth 守卫。 (I think this was what you were heading towards) (我想这就是你的目标)

// auth-guard.ts
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
  let isLoggedIn = this.authService.isUserLoggedIn();

  if(isLoggedIn){
    return true;
  }else{
    this.router.navigate(['/login', {redirectUrl: state.url}]);
    return false;
  }
}

Then the process is the same after a user logs in successfully, except this time you fetch the redirect url from the url parameters instead of the service.那么用户登录成功后的过程是一样的,只是这次你从url参数而不是服务中获取重定向url。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM