Angular2: 如何在使用angular2路由时找到前一页的url?

15
我正在开发一个angular2应用程序,使用了路由器(router)。 当前我在页面/myapp/signup。完成注册后,我会将用户导航到/myapp/login。/myapp/login也可以从我的主页/myapp进行导航。所以,现在当用户使用/myapp/login时,我要回退到上一页。这可以通过使用location.back()来实现。但是,如果用户是从/myapp/signup进入的,我不想回退。因此,我应该检查用户是否是从/myapp/signup进入的,如果是,我希望将其引导到其他地方。我如何知道先前的url以便基于它将用户重定向到特定的状态?

请看这个答案:https://dev59.com/plgR5IYBdhLWcg3wqOxW#74887593 - Kamran Taghaddos
8个回答

25
pairwise 运算符允许获取当前值及其前一个值。 更新
import 'rxjs/add/operator/pairwise';
import 'rxjs/add/operator/filter';
import { Router, NavigationEnd } from '@angular/router';

export class AppComponent {
    constructor(private router: Router) {
        this.router.events
        .filter(e => e instanceof NavigationEnd)
        .pairwise().subscribe((e) => {
            console.log(e);
        });
    }
}

另请参见如何检测Angular中的路由变化?

原始文本(非常老)

注入Router,订阅事件并将它们存储供以后参考。

constructor(private _router: Router) {
  this._router.subscribe(route => {
    this.nextRoute ...
    this.prevRoute ...
  });

1
这种方法帮助我重新编写一个非标准的面包屑导航。非常方便! - Jeff
1
我在某个操作后不得不返回到上一页。这样用最少的代码解决了问题。谢谢! - Aamir Rizwan
如果您需要在刚加载的路由组件上使用previousUrl,则此方法无效,因为它需要在同一组件中进行两个导航事件。 Router / ActivatedRoute是否在任何地方存储先前的URL? - Kesarion
这与Angular无关,只与RXJS有关。https://gist.github.com/btroncone/d6cf141d6f2c00dc6b35#filter 确保您已经导入了所需的内容。 - Günter Zöchbauer
1
现在我正在使用一个服务进行翻译,这是一个很好的实践。此外,当我使用上述 update 示例时,e 的类型是什么?我目前是这样进行hack的:const prev = e[0] const cur = e[1] console.log('Previous url' + prev.url) console.log('Previous url' + cur.url) - Melroy van den Berg
显示剩余8条评论

1

获取前一个URL的字符串的Angular 6更新代码。

import { Component, OnInit } from '@angular/core';
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
            });
    }

1
是的,我会这样做:
@Injectable() // do not forget to register this class as a provider
export class PreviousRouteRecorder implements CanDeactivate<any> {
  constructor(private router: Router) {
  }
  canDeactivate(component: any): Observable<boolean> | boolean {
    localStorage.setItem('previousRoute', this.router.url);
    return true;
  }
}

export const ROUTES: Routes = [
  {
    path: 'first',
    component: FirstComponent,
    canDeactivate: [PreviousRouteRecorder]},
  {
    path: 'second',
    component: SecondComponent
  }
];

export class SecondComponent implements OnInit {
  ngOnInit(){
    console.log(localStorage.getItem('previousRoute'));
  }
}

0
你可以使用 document.referrer 来实现这个功能。
if(document.referrer !== '/myapp/signup'){
    location.back()
}

1
测试时无法工作。在所有情况下,document.referer都不返回任何内容。也许在angular2中它的行为方式不同? - user3205675
我正在使用Angular2的router.navigate来导航到新状态! - user3205675
啊哈,所以你不是来自另一个URL?URL没有改变吗? - Bob van Luijt
我来自另一个URL。我在localhost/myapp/signup,使用Angular Router.navigate方法导航到/myapp/login。由于某种原因,无论我从哪里来到/myapp/login,文档引用始终为空。我认为Angular应该具有此功能,以知道我来自哪个URL。 - user3205675

0

你可以尝试利用OnActivate阶段routerOnActivate方法,这将使你能够访问先前的URL和当前的URL。

routerOnActivate(next: ComponentInstruction, prev: ComponentInstruction) {
  console.log(`Finished navigating from "${prev ? prev.urlPath : 'null'}" to "${next.urlPath}"`);
}

这对我很有效,谢谢,只需要确保导入了ComponentInstruction :) import {Router, ComponentInstruction} from 'angular2/router'; - dazziep
2
这已经过时了。 - Roland

0

如果用户不至少触发两次导航事件,则使用成对实现将无法正常工作,并可能导致小错误。

页面1 -> 页面2 ---> 触发了导航事件,但事件Observable仅具有1个值,因此成对不会发出信号 ---> 用户无法返回到页面1

页面2 -> 页面3 --> 事件Observable现在具有2个元素,成对发出信号

我想知道是否有解决方法?


阅读帮助文档,不要在答案中发布问题和评论。如果您想评论其他答案,但无法执行该操作,请先尝试提升等级。 - PhoneixS
1
@PhoneixS 也许你应该阅读帮助文档,了解并非每个人都可以发表评论。收到你毫无意义的通知真是令人烦恼。 - Hou
我只是在报告这个网站的规则。我也从1个声望和没有评论开始,所以我知道情况是怎样的,这并不意味着不需要遵守规则。 - PhoneixS
我遇到了同样的问题,就像@Hou所评论的那样,成对运算符并没有按照预期工作。这个问题有解决方案吗? - JulianProg

0

您可以使用身份验证守卫设置上一个 URL,并在应用程序的任何位置设置上一个 URL。

canActivate(route: ActivatedRouteSnapshot, snapshot: RouterStateSnapshot) {
                this.commonService.prevRouter = this.router.url;
}

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

 private currentLocation;
 constructor(private location: Location){
    this.currentLocation = this.location.path();  
   }

ngAfterViewInit() {
 let instance = this;
 this.router.parent.subscribe(() => {            
        if (instance.currentLocation != instance.location.path()) {
             console.log("previous -> "+instance.currentLocation+" != next -> "+instance.location.path());             
        }else{
            console.log("previous -> "+instance.currentLocation+" == next -> "+instance.location.path());
        }
    });
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接