为啥我不能在 Angular 2 应用程序中将 RouterStateSnapshot 注入到登录组件中?

Posted

技术标签:

【中文标题】为啥我不能在 Angular 2 应用程序中将 RouterStateSnapshot 注入到登录组件中?【英文标题】:Why Can't I Inject RouterStateSnapshot into Login Component in Angular 2 App?为什么我不能在 Angular 2 应用程序中将 RouterStateSnapshot 注入到登录组件中? 【发布时间】:2018-04-14 07:39:28 【问题描述】:

简单的 Angular 2 问题:当我将 RouterStateSnapshot 注入登录组件中的构造函数时,为什么会出现 DI(依赖注入)错误?我正在尝试在注销之前获取 url,因此我可以在用户重新登录时将其传递(因此它将加载他们最后访问的组件/页面)。事实证明这比我预期的要困难。即使在将它导入并在我的构造函数中包含 RouterStateSnapshot 之后,我也会收到 DI 错误。这就是我在登录组件中的设置方式:

import  ActivatedRoute, ActivatedRouteSnapshot, Router, RouterStateSnapshot  from '@angular/router';

constructor(private router: Router,
            private route: ActivatedRoute,
            private authenticationService: AuthenticationService,
            private alertService: AlertService,
            private state: RouterStateSnapshot,
            private authGuardService: AuthGuardService,
            private idle: Idle)

这里有什么问题? RouterStateSnapshot 与 ActivatedRoute、ActivatedRouteSnapshot 等不同——我可以毫无问题地导入和注入,我缺少什么?为什么我不能以同样的方式注入RouterStateSnapshot?

顺便说一句,我可以在我的 authGuardService 中使用 RouterStateSnapshot,而不会出现问题。它在我的 canActivate() 函数中使用 - 并返回正确的结果。那么在这种情况下有什么不同呢?为什么我不能在我的登录组件中使用它?

【问题讨论】:

【参考方案1】:

我认为您可以从RouterState 获得RouterStateSnapshot。考虑这个例子:

constructor(private router: Router) 
    let routerStateSnapshot = this.router.routerState.snapshot;

【讨论】:

谢谢,这确实让我得到了同样的结果。我可以直接获取网址: let activeUrl = this.router.routerState.snapshot['url'];现在我只需要弄清楚如何从一个滴答声中获取它,因为现在它返回'/login' - 实际上我需要在此之前的活动url。 :) 对我来说它不起作用【参考方案2】:

RouteGuardService.ts

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

import LoginService from './login.service';

@Injectable(
  providedIn: 'root'
)
export class RouteGuardService implements CanActivate 

  constructor(private loginService: LoginService, private router: Router) 
  

  canActivate(activatedRoute: ActivatedRouteSnapshot): boolean 
    if (this.loginService.isLoggedIn()) 
      return true;
    
    this.router.navigate(['login'], queryParams: returnUrl: activatedRoute.routeConfig.path);
    return false;
  

LoginComponent.ts

import Component, OnInit from '@angular/core';
import ActivatedRoute, Router from '@angular/router';
import LoginService from '../service/login.service';

@Component(
  selector: 'app-login',
  templateUrl: './login.component.html',
  styleUrls: ['./login.component.css']
)
export class LoginComponent implements OnInit 
  errorMessage = 'Invalid Credentials';
  invalidLogin = false;
  username = 'in28minutes';
  password = 'novell';
  returnUrl: string;

  constructor(private router: Router, public loginService: LoginService, private activatedRoute: ActivatedRoute) 
  

  ngOnInit(): void 
  

  handleLogin(): any 
    this.returnUrl = this.activatedRoute.snapshot.queryParams.returnUrl || `/welcome/$this.username`;
    if (this.loginService.authenticate(this.username, this.password)) 
      this.router.navigateByUrl(this.returnUrl);
     else 
      this.router.navigate(['login']);
      this.invalidLogin = true;
    
  



app-routing.module.ts

import Component, NgModule from '@angular/core';
import RouterModule, Routes from '@angular/router';
import LoginComponent from './login/login.component';
import TodoListComponent from './todo-list/todo-list.component';
import WelcomeComponent from './welcome/welcome.component';
import ErrorComponent from './error/error.component';
import RouteGuardService from './service/route-guard.service';
import TodoComponent from './todo/todo.component';

const routes: Routes = [
  path: '', component: LoginComponent, canActivate: [RouteGuardService],
  path: 'login', component: LoginComponent,
  path: 'welcome/:username', component: WelcomeComponent, canActivate: [RouteGuardService],
  path: 'todos', component: TodoListComponent, canActivate: [RouteGuardService],
  path: 'todo/:id', component: TodoComponent, canActivate: [RouteGuardService],
  path: '**', component: ErrorComponent
];

@NgModule(
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
)
export class AppRoutingModule 


【讨论】:

【参考方案3】:

如果您想从方法/函数创建returnUrl 而不是使用canActivate 接口或Authguard, 在函数中,

constructor (
    private route: ActivatedRoute,


sampleFunction ()
    this.router.navigate(['/auth/login'], 
        queryParams: 
            returnUrl: this.router.routerState.snapshot.url
        
    )

【讨论】:

以上是关于为啥我不能在 Angular 2 应用程序中将 RouterStateSnapshot 注入到登录组件中?的主要内容,如果未能解决你的问题,请参考以下文章

Angular 2 - 为啥你不能注销输入值

为啥我不能在 python 诅咒窗口中将str()添加到最后一行/列?

为啥我不能在通知中将数组转换为 AnyObject?

为啥我不能在 Swift 中将对象数组返回给 UIStackView? [复制]

为啥我不能在 Ruby 中将块传递给 proc?

为啥我不能在 .net 核心中将静态属性与通知绑定?