如何确定上一页的网址角度?

假设我当前所在的页面的 URL 为 /user/:id。现在从这一页导航到下一页 :id/posts

现在有没有一种方法,让我可以检查什么是以前的网址,即 /user/:id

下面是我的路线

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

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

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

参见 如何在角度上检测路线变化?

@ G ünterZöchbauer 你也可以把它保存在本地仓库,但我不喜欢它) 更好的是在服务中节省,并从中获得这种价值

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

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

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

如果只使用 NavigationEnd,则无法获取以前的 URL。

因为路由器的工作范围从“导航开始”,“路由识别”,... ,到“导航结束”。

你可以问问

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

但即使使用“导航开始”,您仍然无法获得以前的 URL。

现在你需要两两使用。

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);
});
}
    

通过配对,您可以看到 url 的来自和到。

路由识别是从原始地址到目标地址的变化步骤。

所以过滤它,并从它获得以前的网址。

最后但同样重要的是,

将此代码放在父组件或更高级别(例如 app.Component. ts)中

因为这个代码在完成路由之后触发。

更新角度6 +

因为过滤器不是事件的一部分,所以将代码更改为

import { filter, pairwise } from 'rxjs/operators';


this.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);
});

创造一种可注射的服务:

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);
}


//...


}

当我想回到上一页时,我也遇到了类似的问题。 解决方法比我想象的要简单。

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

我希望它能帮到某些人;)

角度6更新代码获取以前的网址作为字符串。

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
});
}

这种方法在角度 > = 6.x 的版本中对我很有效:

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

我使用的是 角度8,而@Franklin-pious 的答案解决了这个问题。在我的示例中,如果在订阅中使用前一个 URL 并附加了视图中的某些数据,那么它会产生一些副作用。

我使用的变通方法是将前面的 URL 作为路由导航中的一个可选参数发送。

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

为了得到组件的这个值:

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

在每个组件的构造函数中注入 this. router 和 this. path,并作为@angle/router 成员导入。

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

可以使用上面提到的 Location。

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

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';

Angular 8 & rxjs 6 in 2019 version

我想分享的解决方案基于其他伟大的解决方案。

首先创建一个服务来监听路由的更改,并将上一个路由保存在行为主题中,然后在构造函数的主 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 location: Location
) {


// ..initial prvious route will be the current path for now
this.previousRoutePath.next(this.location.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]);
}

使用 previousNavigation对象非常简单:

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

我费了好大劲才访问了一个警卫内部的上一个网址。
在没有实现自定义解决方案的情况下,这个解决方案正在为我工作。

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


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

初始 URL 将是前一个 URL 页面。

所有以上答案将加载 URL 多次。如果用户还访问了任何其他组件,这些代码将被加载。

所以更好的使用,服务创建概念

这将工程良好的所有版本的角度。 (请确保将其添加到 app.module 文件中的 provider 数组中!)

角度7 +

实际上,自从 Angular 7.2以来,就不需要使用服务来保存以前的 URL 了。您可以只使用 state 对象在链接到登录页面之前设置最后一个 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) {}
}

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

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
});
};
}
    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);
});
}

参考资料: 以角度获取上一个 URL

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

    @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()
}

现在您可以通过从 service 调用 getPreviousUrl ()方法来获取以前的 URL

最简单的方法

正如前面提到的 给你,请简单地使用来自 @angular/commonLocation

例子

在你的 组件

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




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


public returnPreviousUrl(): void {
this._location.back();
}
}

在你的 组件

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

最新的完整答案,包括刷新。

服务

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


@Injectable()
export class RouterService{


private prevUrl?: any = undefined;


constructor(private router: Router){
router.events.pipe(
filter(e => e instanceof NavigationEnd),
pairwise()
).subscribe(x=>{
this.prevUrl = x[0].urlAfterRedirects;
localStorage.setItem("prevUrl", this.prevUrl);
})
}
public getPrevUrl(){
console.log(this.prevUrl)
return this.prevUrl;
}
public getCurrUrl(){
return  this.router.url;
}
public checkStorage(){
console.log("checkign storage")
this.prevUrl= localStorage.getItem("prevUrl")
}
}

应用程序组件

import { RouterService } from './shared/services/router-service';


export class AppComponent {


constructor(private routerSvc: RouterService ) {}
ngOnInit() {
this.routerSvc.checkStorage()
}
}

在 App.module 中包含 service

@NgModule({
...
providers: [
RouterService
],


组成部分


import { RouterService  } from '../services/router-service';


export class MyComponent implements OnInit {


constructor(private routerSvc: RouterService) { }
  

ngOnInit(): void {
console.log(this.routerSvc.getPrevUrl())
}


}

您可以尝试以下示例代码:

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

previousUrl = '';


constructor(
private readonly location: Location, private readonly router: Router) {
this.router.events
.pipe(filter((evt: Event): evt is RoutesRecognized => evt instanceof RoutesRecognized), pairwise())
.subscribe((events: RoutesRecognized[]) => {
this.previousUrl = events[0].urlAfterRedirects;
});
}

任何’的类型声明失去了类型安全性。最好提供一个更具体的类型。

TypeScript 的 任何类型是所有其他类型的超类型和子类型,并允许取消对所有属性的引用。因此,任何类型都是危险的——它可以掩盖严重的编程错误,而且它的使用首先会破坏静态类型的价值。

在 Angular GitHub 中有一个问题正在考虑之中,这个问题可以让这个过程变得非常简单,也就是 Router.previousUrl。请把你的问题,使它跨越所需的20为了使它成为积压:

Https://github.com/angular/angular/issues/45685

您可以简单地将该解决方案与 RXJX例子灵感一起使用

Html

<p>Previous URL: \{\{ previousUrl }}</p>
<p>Current URL: \{\{ currentUrl }}</p>

应用程序组件

previousUrl: string = null
currentUrl: string = null


ngOnInit() {
this.router.events.pipe(
filter((event) => event instanceof NavigationEnd)
).subscribe((event: NavigationEnd) => {
this.previousUrl = this.currentUrl;
this.currentUrl = event.url;
this.urlService.setPreviousUrl(this.previousUrl);
});
}

注射器服务

import { Injectable } from '@angular/core';
import { BehaviorSubject, Observable, take } from 'rxjs';


@Injectable()
export class UrlService {
private previousUrl: BehaviorSubject<string> = new BehaviorSubject<string>(null);
public previousUrl$: Observable<string> = this.previousUrl.asObservable();


constructor() { }
setPreviousUrl(previousUrl: string) {
this.previousUrl.next(previousUrl);
}
}

只需要实现前面的函数来导航

public goToPrevious(): void {
let obsValue = undefined;
const sub = this.urlService.previousUrl$.pipe(take(1)).subscribe(value => obsValue = value);
sub.unsubscribe();


console.log('url', obsValue)
this.router.navigateByUrl(obsValue)
}

还可以使用 管道异步在模板中显示以前的 in 值

其他。组件

<p>Previous URL: \{\{ previousUrl | async }}</p>

其他组件

export class OtherComponent implements OnInit {
previousUrl: Observable<string> = this.urlService.previousUrl$;
constructor(private urlService: UrlService) { }


ngOnInit() {
this.urlService.previousUrl$.subscribe((previousUrl: string) => {
console.log('previous url: ', previousUrl);
});
}
}