Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/29.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angular 以角度保存/恢复路由器状态_Angular_Angular Routing - Fatal编程技术网

Angular 以角度保存/恢复路由器状态

Angular 以角度保存/恢复路由器状态,angular,angular-routing,Angular,Angular Routing,当用户到达我的应用程序中的一个路由时(该路由受特殊保护),我会将他重定向到一个登录路由,以便执行身份验证 然而,在成功的身份验证之后,我不想将她重定向回她最初到达的路线 如何在Angular中保留中间路由状态,然后重定向到它? 我所说的路由状态是指以下情况: 路线本身,即路径 所有查询字符串参数 散列字符串 一种方法是使用服务 以下是一个示例服务: import { Injectable } from '@angular/core'; import { IUser } from './use

当用户到达我的应用程序中的一个路由时(该路由受特殊保护),我会将他重定向到一个登录路由,以便执行身份验证

然而,在成功的身份验证之后,我不想将她重定向回她最初到达的路线

如何在Angular中保留中间路由状态,然后重定向到它?

我所说的路由状态是指以下情况:

  • 路线本身,即路径
  • 所有查询字符串参数
  • 散列字符串

    • 一种方法是使用服务

      以下是一个示例服务:

      import { Injectable } from '@angular/core';
      
      import { IUser } from './user';
      import { MessageService } from '../messages/message.service';
      
      @Injectable()
      export class AuthService {
          currentUser: IUser;
          redirectUrl: string;
      
          constructor(private messageService: MessageService) { }
      
          isLoggedIn(): boolean {
              return !!this.currentUser;
          }
      
          login(userName: string, password: string): void {
              if (!userName || !password) {
                  this.messageService.addMessage('Please enter your userName and password');
                  return;
              }
              if (userName === 'admin') {
                  this.currentUser = {
                      id: 1,
                      userName: userName,
                      isAdmin: true
                  };
                  this.messageService.addMessage('Admin login');
                  return;
              }
              this.currentUser = {
                  id: 2,
                  userName: userName,
                  isAdmin: false
              };
              this.messageService.addMessage(`User: ${this.currentUser.userName} logged in`);
          }
      
          logout(): void {
              this.currentUser = null;
          }
      }
      
      完整代码如下:

      但是如果你找不到它。。。以下是登录组件代码:

      import { Component } from '@angular/core';
      import { NgForm } from '@angular/forms';
      import { Router } from '@angular/router';
      
      import { AuthService } from './auth.service';
      
      @Component({
          templateUrl: './app/user/login.component.html'
      })
      export class LoginComponent {
          errorMessage: string;
          pageTitle = 'Log In';
      
          constructor(private authService: AuthService,
                      private router: Router) { }
      
          login(loginForm: NgForm) {
              if (loginForm && loginForm.valid) {
                  let userName = loginForm.form.value.userName;
                  let password = loginForm.form.value.password;
                  this.authService.login(userName, password);
      
                  if (this.authService.redirectUrl) {
                      this.router.navigateByUrl(this.authService.redirectUrl);
                  } else {
                      this.router.navigate(['/products']);
                  }
              } else {
                  this.errorMessage = 'Please enter a user name and password.';
              };
          }
      }
      
      以及要完成的身份验证保护服务:

      import { Injectable } from '@angular/core';
      import { ActivatedRouteSnapshot, RouterStateSnapshot, Router, Route,
               CanActivate, CanActivateChild, CanLoad } from '@angular/router';
      
      import { AuthService } from './auth.service';
      
      @Injectable()
      export  class AuthGuard implements CanActivate, CanActivateChild, CanLoad {
      
      constructor(private authService: AuthService,
                  private router: Router) { }
      
      canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
          console.log('In canActivate: ' + state.url);
          return this.checkLoggedIn(state.url);
      }
      
      canActivateChild(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
          console.log('In canActivateChild: ' + state.url);
          return this.checkLoggedIn(state.url);
      }
      
      canLoad(route: Route): boolean {
          console.log('In canLoad: ' + route.path);
          return this.checkLoggedIn(route.path);
      }
      
      checkLoggedIn(url: string): boolean {
          if (this.authService.isLoggedIn()) {
              return true;
          }
      
          // Retain the attempted URL for redirection
          this.authService.redirectUrl = url;
          this.router.navigate(['/login']);
          return false;
      }
      

      }

      在玩了一会儿路由器之后,我终于实现了我想要的解决方案。我将在这里与你分享

      下面是
      IntermediateNavigationService
      的实现:

      从'rxjs/Subscription'导入{Subscription};
      从'@angular/Router'导入{NavigationCancel,NavigationEnd,Router};
      从“@angular/core”导入{Injectable};
      @可注射()
      导出类中介服务{
      私有savedUrl:string;
      专用路由器订阅:订阅;
      构造函数(专用路由器:路由器){
      }
      startWatch(){
      this.routerSubscription=this.router.events
      .订阅(事件=>{
      if(导航的事件实例取消){
      //正在从已取消的路由保存URL。
      这个.saveUrl(event.url);
      }else if(NavigationEnd的事件实例){
      //若用户离开登录页面,则清除保存的URL。
      如果(!event.url.match(/^\/登录/){
      if(this.hasSavedUrl()){
      这个.clearsavedur();
      }
      }
      }
      })
      ;
      }
      秒表(){
      this.routerSubscription.unsubscribe();
      }
      saveUrl(url:string){
      this.savedUrl=url;
      }
      哈萨维杜尔(){
      return!!this.savedUrl;
      }
      getSavedUrl(){
      返回这个.savedUrl;
      }
      Clearsavedur(){
      this.savedUrl=null;
      }
      goToSavedUrl():承诺{
      返回this.router.navigateByUrl(this.savedUrl)。然后(结果=>{
      如果(结果){
      这个.clearsavedur();
      }
      返回结果;
      });
      }
      }
      
      这项服务背后的理念非常简单。当被
      startWatch()
      方法激活时(您应该在应用程序生命周期中尽早这样做,例如在AppComponent构造函数中),它开始监视路由器事件,特别是过滤
      NavigationCancel
      NavigationEnd
      事件

      • 当发生
        NavigationCancel
        时,这意味着我们的身份验证路由保护阻止了对目标路由的导航。因此,我们将跳过的URL保存在服务私有变量中

      • 当发生
        NavigationEnd
        时,我们检查用户是否离开了我们的登录路径。在这种情况下,我们对保存保存的URL不再感兴趣,因此我们将清除它。否则,当用户被重定向到他不再感兴趣的URL时,可能会导致奇怪的行为

      成功登录后,我们只需发布以下代码:

      if(this.intermediateNavigationService.hasSavedUrl()){
      this.intermediateNavigationService.goToSavedUrl();
      }否则{
      this.navigationService.redirectAfterSignIn();
      }
      
      简而言之:我们只是检查是否有保存的URL,然后导航到它,如果没有重定向到默认的URL

      如果您对某个时刻的状态不再感兴趣,只需调用
      stopWatch()
      ,即可取消路由器事件订阅。这可以在成功登录后进行,实际上是为了保留资源(如果您不打算将此服务用于与身份验证无关的类似行为)

      如果用户已经通过身份验证,则无需调用
      startWatch()

      以下是您的
      AppComponent
      的外观:

      从'@angular/core'导入{Component as NgComponent};
      从“./authentication/authentication state.service”导入{AuthenticationStateService};
      从“./services/intermediate-navigation.service”导入{IntermediateNavigationService};
      @NgComponent({})
      导出类MyAppComponent{
      建造师(
      私有authenticationStateService:authenticationStateService,
      私人中介服务:中介服务
      ) {
      //启用中间URL处理。
      如果(!this.authenticationStateService.isAuthenticated()){
      this.intermediateNavigationService.startWatch();
      }
      //正在侦听身份验证事件。
      此.authenticationStateService.onAuthenticated().subscribe(()=>{
      this.intermediateNavigationService.stopWatch()
      });
      }
      }
      

      我希望它能帮助别人。

      你好,黛博拉!谢谢你的回答。然而,我更感兴趣的是从路由器获取当前URL的部分,以及在登录后实际重定向回它的部分。你的答案中缺少这两部分。我提供了完整源代码的链接。。。但是如果你找不到它。。。我在上面的答案中添加了登录组件代码。