最後のページに戻る方法


369

Angular 2の最後のページに戻るスマートな方法はありますか?

何かのようなもの

this._router.navigate(LASTPAGE);

たとえば、ページCにはGo Backボタンがあり、

  • ページA->ページC、クリックしてページAに戻ります。

  • ページB->ページC、クリックしてページBに戻る。

ルーターにはこの履歴情報がありますか?

回答:


671

実際には、「Back」APIを所有する組み込みのLocationサービスを利用できます。

ここに(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
アミールSasson

7
価値のあるものについては、Angular2 APIの公式ドキュメントでLocation次のように述べています。@Sasxaの答えは明らかにRouterこれを行う方法を示しています。ただし、このLocation方法の方が明らかに便利です。Routerメソッドがメソッドよりも正しいかもしれない理由を誰かが知っていLocationますか?
Andrew Willems

2
@Andrew:this.location.back()を使用すると、2回戻ることができないという問題が発生しました。最初のサイトに戻ります。
ヨハネス

1
@ yt61、わからない、おそらく再利用可能ですか?または、さまざまなルートから指定されたページにアクセスできるため、戻るルートが事前にわからない場合。
Amir Sasson

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 2018

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>

すごい!
Rafael de Castro

1
このページで更新し、「this.location.back()」をトリガーするボタンをクリックすると、ページの更新がトリガーされます。以前のパスが存在するかどうかをLocationモジュールが検出できる方法はありますか?
Henry LowCZ

お疲れ様!;)
elciospy

ユーザーが[戻る]ボタンが存在するページに直接アクセスした場合や、ボタンをクリックした場合は、ブラウザー(プラットフォーム)の履歴に応じて、アプリから前のページに移動します。
hastrb

今後の読者のために、APIドキュメントを
hastrb

24

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 2016年

1
@smartmouse私はそうは思わない、ドキュメントがあるrouterOnActivate
Bojan Kogoj '28

4
この回答のrouterOnActivate()リンクが壊れています。これはリリースバージョンで行う方法ではないようです。
rmcsharry 2017

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-buttonおよびを削除してくださいcolor


このアプローチは名前付きルーターアウトレットでも機能しますか?ページにいくつかあり、そのうちの1つだけに戻りたいとしましょう。これでうまくいくでしょうか。
rrd 2018

その場合は、別の方法を使用する必要があります。2つの異なるルーターコンセントに同じ戻るボタンがあった場合、おそらく両方とも同じことを行い、最後に変更されたルーターコンセントに戻ります。
2018

名前付きアウトレットの場合、このアプローチが機能することがわかりました: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

特定のリンクでページを開いて、ページツリーのページに戻るにはどうすればよいですか?
Ivan

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で戻るボタンを押すと、ユーザーをWebページではない前のページにリダイレクトします。


ActivatedRouteをインポートし、それをqueryParamsサブスクリプションでルーターの代わりに使用する必要があります(たとえば、this.route.queryParams.subscribe)。それ以外の場合は機能するようです。
Stephen Kaiser

私にとっては、角度4でもルーター自体で正常に動作しています
Puneeth Rai

1
最良の回答ですが、Angular 5(xまで)では、 "ActivatedRoute"のオブジェクトを挿入し、このオブジェクトでqueryParamsを使用する必要があります(Stephen Kaiserが既に述べています)。
Satria


3

ページを更新せずに戻るには、次のようにhtmlで実行できます javascript:history.back()

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

Location代わりにサービスを使用することをお勧めします。公式API
hastrb



弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.