如何确定Angular中的上一页网址?

时间:2016-12-08 11:58:21

标签: angular angular2-routing

假设我当前位于包含网址/user/:id的网页上。现在,从此页面导航到下一页:id/posts

现在有办法,以便我可以检查以前的网址是什么,即/user/:id

以下是我的路线

export const routes: Routes = [
  { 
    path: 'user/:id', component: UserProfileComponent
  },
  {  
    path: ':id/posts', component: UserPostsComponet 
  }
];

19 个答案:

答案 0 :(得分:44)

也许所有其他答案都是针对角度2.X。

现在它不适用于角度5.X. 我正在使用它。

只有NavigationEnd,你无法获得以前的网址。

因为路由器从“NavigationStart”,“RoutesRecognized”,......,到“NavigationEnd”。

您可以查看

    router.events.forEach((event) => {
  console.log(event);
});

但即使使用“NavigationStart”,你仍然无法获得以前的网址。

现在你需要成对使用。

import 'rxjs/add/operator/filter';
import 'rxjs/add/operator/pairwise';

constructor(private router: Router) {
  this.router.events
    .filter(e => e instanceof RoutesRecognized)
    .pairwise()
    .subscribe((event: any[]) => {
      console.log(event[0].urlAfterRedirects);
    });
}

使用pairwise,您可以看到来自和的URL。

“RoutesRecognized”是从原点到目标网址的更改步骤。

所以过滤它并从中获取以前的URL。

最后但并非最不重要的,

此代码放置父组件或更高版本(例如,app.component.ts)

因为此代码在完成路由后触发。

答案 1 :(得分:40)

您可以订阅路线更改并存储当前事件,以便在下次发生时使用它

previousUrl: string;
constructor(router: Router) {
  router.events
  .filter(event => event instanceof NavigationEnd)
  .subscribe(e => {
    console.log('prev:', this.previousUrl);
    this.previousUrl = e.url;
  });
}

另见How to detect a route change in Angular 2?

答案 2 :(得分:19)

创建可注射服务:

import { Injectable } from '@angular/core';
import { Router, RouterEvent, NavigationEnd } from '@angular/router';

 /** A router wrapper, adding extra functions. */
@Injectable()
export class RouterExtService {

  private previousUrl: string = undefined;
  private currentUrl: string = undefined;

  constructor(private router : Router) {
    this.currentUrl = this.router.url;
    router.events.subscribe(event => {
      if (event instanceof NavigationEnd) {        
        this.previousUrl = this.currentUrl;
        this.currentUrl = event.url;
      };
    });
  }

  public getPreviousUrl(){
    return this.previousUrl;
  }    
}

然后在您需要的任何地方使用它。要尽快存储当前变量,必须在AppModule中使用该服务。

// AppModule
export class AppModule {
  constructor(private routerExtService: RouterExtService){}

  //...

}

// Using in SomeComponent
export class SomeComponent implements OnInit {

  constructor(private routerExtService: RouterExtService, private location: Location) { } 

  public back(): void {
    this.location.back();
  }

  //Strange name, but it makes sense. Behind the scenes, we are pushing to history the previous url
  public goToPrevious(): void {
    let previous = this.routerExtService.getPreviousUrl();

    if(previous)
      this.routerExtService.router.navigateByUrl(previous);
  }

  //...

}

答案 3 :(得分:10)

Angular 6更新了以前的url为字符串的代码。

import { Router, RoutesRecognized } from '@angular/router';
import { filter, pairwise } from 'rxjs/operators';


export class AppComponent implements OnInit {

    constructor (
        public router: Router
    ) {
    }

    ngOnInit() {
        this.router.events
            .pipe(filter((e: any) => e instanceof RoutesRecognized),
                pairwise()
            ).subscribe((e: any) => {
                console.log(e[0].urlAfterRedirects); // previous url
            });
    }

答案 4 :(得分:7)

我使用的是 Angular 8 ,@ franklin-pious的回答解决了这个问题。就我而言,如果在视图中附加了某些数据,则将前一个URL保留在订阅中会带来一些副作用。

我使用的解决方法是在路由导航中将以前的网址作为可选参数发送。

this.router.navigate(['/my-previous-route', {previousUrl: 'my-current-route'}])

并在组件中获取此值:

this.route.snapshot.paramMap.get('previousUrl')

this.router和this.route分别注入每个组件的构造函数中,并作为@ angular / router成员导入。

import { Router, ActivatedRoute }   from '@angular/router';

答案 5 :(得分:6)

适用于ANGULAR 7 +

实际上,从Angular 7.2开始,不需要使用服务来保存先前的url。您可以使用状态对象设置最后的URL,然后再链接到登录页面。这是一个登录方案的示例。

@Component({ ... })
class SomePageComponent {
  constructor(private router: Router) {}

  checkLogin() {
    if (!this.auth.loggedIn()) {
      this.router.navigate(['login'], { state: { redirect: this.router.url } });
    }
  }
}
@Component({...})
class LoginComponent {
  constructor(private router: Router) {}

  backToPreviousPage() {
    const { redirect } = window.history.state;

    this.router.navigateByUrl(redirect || '/homepage');
  }
}
----------------

此外,您还可以在模板中传递数据:

@Component({
  template: '<a routerLink="/some-route" [state]="{ redirect: router.url}">Go to some route</a>'
})
class SomePageComponent {
  constructor(public router: Router) {}
}

答案 6 :(得分:4)

这对我来说在角度6中起作用:

this.router.events
            .subscribe((event) => {
              if (event instanceof NavigationStart) {
                window.localStorage.setItem('previousUrl', this.router.url);
              }
            });

答案 7 :(得分:3)

Angular 8和rxjs 6在2019版中

我想在其他出色的解决方案的基础上分享解决方案。

首先提供服务以侦听路线更改并将最后的前一条路线保存在“行为主体”中,然后在构造函数中的主app.component中提供此服务,然后使用该服务在需要时获取所需的前一条路线

用例:您想要将用户重定向到广告页面,然后将其自动重定向到他/她的来源,因此您需要使用上一条最后的路由。

// service : route-events.service.ts

import { Injectable } from '@angular/core';
import { Router, RoutesRecognized } from '@angular/router';
import { BehaviorSubject } from 'rxjs';
import { filter, pairwise } from 'rxjs/operators';
import { Location } from '@angular/common';

@Injectable()
export class RouteEventsService {

    // save the previous route
  public previousRoutePath = new BehaviorSubject<string>('');

  constructor(
    private router: Router,
    private locatoin: Location
  ) {

    // ..initial prvious route will be the current path for now
    this.previousRoutePath.next(this.locatoin.path());


    // on every route change take the two events of two routes changed(using pairwise)
    // and save the old one in a behavious subject to access it in another component
    // we can use if another component like intro-advertise need the previous route
    // because he need to redirect the user to where he did came from.
    this.router.events.pipe(
      filter(e => e instanceof RoutesRecognized),
      pairwise(),
        )
    .subscribe((event: any[]) => {
        this.previousRoutePath.next(event[0].urlAfterRedirects);
    });

  }
}

在app.module中提供服务

  providers: [
    ....
    RouteEventsService,
    ....
  ]

将其注入app.component

  constructor(
    private routeEventsService: RouteEventsService
  )

最终在所需的组件中使用保存的先前路线

  onSkipHandler(){
    // navigate the user to where he did came from
    this.router.navigate([this.routeEventsService.previousRoutePath.value]);
  }

答案 8 :(得分:2)

最简单的方法

正如前面提到的 here,请简单地使用来自 Location@angular/common

示例

<块引用>

在您的 component.ts

import { Location } from '@angular/common';


@Component({...})
export class AuthenticationComponent {
    constructor(private _location: Location) {}

    public returnPreviousUrl(): void {
        this._location.back();
    }
}
<块引用>

在您的 component.html

<div (click)="returnPreviousUrl()">return</div>

答案 9 :(得分:2)

您可以使用here中提到的位置信息。

如果在新标签页上打开了链接,这是我的代码

navBack() {
    let cur_path = this.location.path();
    this.location.back();
    if (cur_path === this.location.path())
     this.router.navigate(['/default-route']);    
  }

必填项

import { Router } from '@angular/router';
import { Location } from '@angular/common';

答案 10 :(得分:1)

@GünterZöchbauer你也可以将它保存在localstorage但我不喜欢它) 更好地保存服务并从那里获得这个价值

 constructor(
        private router: Router
      ) {
        this.router.events
          .subscribe((event) => {
            if (event instanceof NavigationEnd) {
              localStorage.setItem('previousUrl', event.url);
            }
          });
      }

答案 11 :(得分:0)

使用previousNavigation对象非常简单:

this.router.events
  .pipe(
    filter(e => e instanceof NavigationEnd && this.router.getCurrentNavigation().previousNavigation),
    map(() => this.router.getCurrentNavigation().previousNavigation.finalUrl.toString()),
  )
  .subscribe(previousUrl => {}); 

答案 12 :(得分:0)

我很难在防护中访问以前的网址。
无需实施自定义解决方案,该解决方案对我有用。

public constructor(private readonly router: Router) {
};

public ngOnInit() {
   this.router.getCurrentNavigation().previousNavigation.initialUrl.toString();
}

初始网址将是上一个网址页面。

答案 13 :(得分:0)

这个简单的解决方案对我有用。

import 'rxjs/add/operator/pairwise';
import { Router } from '@angular/router';

export class TempComponent {
    constructor(private router: Router) {
        this.router.events.pairwise().subscribe((event) => {
            console.log(event); // NavigationEnd will have last and current visit url
        });
    };
}

答案 14 :(得分:0)

import { Router, RoutesRecognized } from '@angular/router';
import { filter, pairwise } from 'rxjs/operators';

constructor(
    private router: Router
  ) {
    
  }


ngOnInit(){
this.router.events
.pipe(filter((evt: any) => evt instanceof RoutesRecognized), pairwise())
.subscribe((events: RoutesRecognized[]) => {
  
   let prevUrl = events[0].urlAfterRedirects;
  console.log('previous url', prevUrl);
  console.log('current url', events[1].urlAfterRedirects);
});
}

答案 15 :(得分:0)

参考:Get Previous URL in Angular

作为服务的一部分使用是更好的方法

@Injectable({
  providedIn: 'root'
})
export class RoutingStateService
{
  private history = [];

  constructor(private router: Router)
  {
    this.loadRouting();
  }

  public loadRouting(): void
  {
    this.router.events
      .pipe(filter(event => event instanceof NavigationEnd))
      .subscribe(({urlAfterRedirects}: NavigationEnd) => {
        this.history = [...this.history, urlAfterRedirects];
      });
  }

  public getHistory(): string[]
  {
    return this.history;
  }

  public getPreviousUrl(): string
  {
    return this.history[this.history.length - 2];
  }
}

在 init 上的组件中的下一步

ngOnInit(): void {
     this.routingStateService.loadRouting()
  }

现在您可以通过从服务中调用 getPreviousUrl() 方法来获取之前的 url

答案 16 :(得分:-2)

以上所有ANSWER都会多次加载URL。如果用户还访问了其他组件,则将加载这些代码。

使用更好,服务创造理念。 https://community.wia.io/d/22-access-the-previous-route-in-your-angular-5-app

这将在所有Angular版本中正常运行。 (请确保将其添加到app.module文件中的providers数组中!)

答案 17 :(得分:-2)

使用rxjx中的pairwise,可以更轻松地实现此目的。 从'rxjs / operators'导入{filter,pairwise};

previousUrl: string;
constructor(router: Router) {
router.events
  .pipe(filter((evt: any) => evt instanceof RoutesRecognized), pairwise())
  .subscribe((events: RoutesRecognized[]) => {
  console.log('previous url', events[0].urlAfterRedirects);
  console.log('current url', events[1].urlAfterRedirects);
  this.previousUrl = events[0].urlAfterRedirects;
});

}

答案 18 :(得分:-5)

当我想回到上一页时,我遇到了类似的问题。 解决方案比我想象的要容易。

<button [routerLink]="['../']">
   Back
</button>

然后它返回到父网址。我希望它会帮助某人;)