如何返回上一页


366

有没有一种聪明的方法可以返回Angular 2的最后一页?

就像是

this._router.navigate(LASTPAGE);

例如,页面C有一个Go Back按钮,

  • 页面A->页面C,单击它,回到页面A。

  • 页面B->页面C,单击它,返回页面B。

路由器是否有此历史记录信息?

Answers:


669

实际上,您可以利用内置的位置服务,该服务拥有“后退” API。

此处(在TypeScript中):

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

@Component({
  // component's declarations here
})
class SomeComponent {

  constructor(private _location: Location) 
  {}

  backClicked() {
    this._location.back();
  }
}

编辑:如@ charith.arumapperuma所述,Location应从中导入,@angular/common因此该import {Location} from '@angular/common';行很重要。


75
在较旧的Angular 2版本中,应从“ angular2 / router”导入位置。在较新的版本中,应从“ @ angular / common”导入。
charith.arumapperuma

2
如果您将其内置在框架中,则看不到使用“本机”“ window.history.back();”的任何理由。这是一个HTML5特征(developer.mozilla.org/en-US/docs/Web/API/Window/history
阿米尔萨松

7
对于它的价值,官方的Angular2 API文档Location指出:“注意:最好使用Router服务来触发路由更改。仅在需要与路由之外进行交互或创建标准化URL时才使用Location。” @Sasxa的答案确实显示了一种Router用于执行此操作的方法。但是,该Location方法绝对更方便。有谁知道为什么该Router方法可能比该Location方法更正确?
安德鲁·威廉姆斯

2
@Andrew:我遇到了问题,如果使用this.location.back(),则不能再返回两次。您将跳回到初始站点。
约翰内斯'09

1
@ yt61,不确定,也许可以重复使用?或者您是否可以从各种路线到达指定页面,所以您事先不知道要返回的路线。
阿米尔·萨森

111

在Angular 2.x / 4.x 的最终版本中-这是文档https://angular.io/api/common/Location

/* typescript */

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

@Component({
// declare component here
})
export class MyComponent {

  // inject location into component constructor
  constructor(private location: Location) { }

  cancel() {
    this.location.back(); // <-- go back to previous location on cancel
  }
}

1
导航回上一屏幕时,我们可以保留输入的值,而无需使用服务中的对象。
Vignesh

在location.back()执行时如何显示动画?
下雪基地

48

<button backButton>BACK</button>

您可以将其放入可以附加到任何可点击元素的指令中:

import { Directive, HostListener } from '@angular/core';
import { Location } from '@angular/common';

@Directive({
    selector: '[backButton]'
})
export class BackButtonDirective {
    constructor(private location: Location) { }

    @HostListener('click')
    onClick() {
        this.location.back();
    }
}

用法:

<button backButton>BACK</button>

棒极了!
拉斐尔·德卡斯特罗

1
如果刷新此页面,然后单击触发“ this.location.back()”的按钮,它将仅触发页面刷新。定位模块是否可以通过任何方式检测先前的路径是否存在?
Henry LowCZ

做人好!;)
elciospy

请记住,如果用户直接转到存在“后退”按钮的页面,并且单击了按钮……,那么根据浏览器(平台)的历史记录,他将被退出应用程序并转到上一页。
hastrb

对于未来的读者,请参阅API文档
hastrb,

23

经过Angular 5.2.9测试

如果您使用的锚,而不是一个按钮,你必须更加被动的链接href="javascript:void(0)"进行角向位置的工作。

app.component.ts

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

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent {

  constructor( private location: Location ) { 
  }

  goBack() {
    // window.history.back();
    this.location.back();

    console.log( 'goBack()...' );
  }
}

app.component.html

<!-- anchor must be a passive link -->
<a href="javascript:void(0)" (click)="goBack()">
  <-Back
</a>

我建议您创建一个'clickPreventDefault'指令,而不要使用javascript:void(0)。像... @Directive({ selector: '[clickPreventDefault]' }) export class ClickPreventDefaultDirective { @HostListener("click", ["$event"]) onClick($event: Event) { $event.preventDefault(); } }
bmd

谢谢@bmd,这是一种更精致的方法,但是也可以使用。另一个可行的解决方案是不要使用herf:<a (click)="goBack()">,尽管这种方式不会传递HTML验证程序。
JavierFuentes

20

您可以routerOnActivate()在路由类上实现方法,它将提供有关先前路由的信息。

routerOnActivate(nextInstruction: ComponentInstruction, prevInstruction: ComponentInstruction) : any

然后,您可以使用router.navigateByUrl()并传递从生成的数据ComponentInstruction。例如:

this._router.navigateByUrl(prevInstruction.urlPath);

这对Angular 2.1.0仍然有效吗?
smartmouse

1
@smartmouse我认为不是,这里有文档routerOnActivate
Bojan Kogoj,2016年

4
此答案中的routerOnActivate()链接已损坏。似乎在发行版中不是这样做的。
rmcsharry17年

14

当我需要移回文件系统中时,也可以为我工作。 PS @角度:“ ^ 5.0.0”

<button type="button" class="btn btn-primary" routerLink="../">Back</button>

7
我希望这能行得通,但是它会移回到其上方的下一个路线-而不是导航至页面之前的路线。很高兴知道这个方法的存在,但是如果您的组件有多个入口点,则此方法将永远只返回到其上方的路由,而不是源于此的路由。
Scott Byers

当我写“当我需要移回文件系统时”时:)对我来说,这种行为也是意料之外的。
Shevtsiv Andriy

12

我做了一个按钮,可以在应用程序的任何地方重复使用。

创建此组件

import { Location } from '@angular/common';
import { Component, Input } from '@angular/core';

@Component({
    selector: 'back-button',
    template: `<button mat-button (click)="goBack()" [color]="color">Back</button>`,
})
export class BackButtonComponent {
    @Input()color: string;

  constructor(private location: Location) { }

  goBack() {
    this.location.back();
  }
}

然后在需要后退按钮时将其添加到任何模板中。

<back-button color="primary"></back-button>

注意:这是使用Angular Material,如果您不使用该库,请删除mat-buttoncolor


这种方法是否适用于命名路由器插座?假设我在页面上有几个,只想返回其中一个,这样行得通吗?
rrd

在这种情况下,您将不得不使用其他方法。如果您在两个不同的路由器插座中具有相同的后退按钮,则它们可能都将执行相同的操作,并返回更改后的最后一个路由器插座。
Todd Skelton '18

对于命名商店,我发现这种方法有效:this.router.navigate(['../'],{relativeTo:this.route})
rrd

如何在另一个组件中使用此组件?
RN库什瓦哈

12

在所有这些很棒的答案之后,我希望我的答案能找到人并帮助他们。我写了一个小服务来跟踪路线历史。来了

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

@Injectable()
export class RouteInterceptorService {
  private _previousUrl: string;
  private _currentUrl: string;
  private _routeHistory: string[];

  constructor(router: Router) {
    this._routeHistory = [];
    router.events
      .pipe(filter(event => event instanceof NavigationEnd))
      .subscribe((event: NavigationEnd) => {
        this._setURLs(event);
      });
  }

  private _setURLs(event: NavigationEnd): void {
    const tempUrl = this._currentUrl;
    this._previousUrl = tempUrl;
    this._currentUrl = event.urlAfterRedirects;
    this._routeHistory.push(event.urlAfterRedirects);
  }

  get previousUrl(): string {
    return this._previousUrl;
  }

  get currentUrl(): string {
    return this._currentUrl;
  }

  get routeHistory(): string[] {
    return this._routeHistory;
  }
}

在尝试了或多或少的所有解决方案之后,我发现这种解决方案是一种更一致的方法
A. D'Alfonso

如果我打开特定链接上的页面并且希望它返回到页面树中的页面怎么办?
伊万

8

我导航到其他页面时的方式是通过传递当前位置来添加查询参数

this.router.navigate(["user/edit"], { queryParams: { returnUrl: this.router.url }

阅读组件中的此查询参数

this.router.queryParams.subscribe((params) => {
    this.returnUrl = params.returnUrl;
});

如果存在returnUrl,则启用后退按钮,并且当用户单击后退按钮时

this.router.navigateByUrl(this.returnUrl); // Hint taken from Sasxa

这应该能够导航到上一页。与使用location.back相比,我认为上述方法更安全,考虑到用户直接登陆到您的页面的情况,并且如果他按下带有location.back的后退按钮,它将把用户重定向到上一个页面,该页面将不是您的网页。


需要导入ActivatedRoute并在queryParams订阅上使用它而不是Router(例如,this.route.queryParams.subscribe),但否则似乎可以正常工作!
斯蒂芬·凯泽

对我来说,即使是在4角做工精细与路由器本身
Puneeth拉伊

1
最佳答案,但是在Angular 5中(最多x?),您需要注入“ ActivatedRoute”对象,并对该对象使用queryParams,正如Stephen Kaiser所述。
萨特里亚


3

要返回而不刷新页面,我们可以在html中进行如下操作 :javascript:history.back()

<a class="btn btn-danger" href="javascript:history.back()">Go Back</a>

我建议Location改为使用服务。官方API
hastrb



2

另一种解决方案

window.history.back();


为我工作location.back()也可以工作,但我无法使用--prod进行编译
Alex
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.