Wie gehe ich zurück zur letzten Seite?

366

Gibt es eine clevere Möglichkeit, die letzte Seite in Angular 2 zurückzurufen?

Etwas wie

this._router.navigate(LASTPAGE);

Zum Beispiel hat Seite C eine Go BackSchaltfläche,

  • Seite A -> Seite C, klicken Sie darauf, zurück zu Seite A.

  • Seite B -> Seite C, klicken Sie darauf, zurück zu Seite B.

Hat der Router diese Verlaufsinformationen?

Hongbo Miao
quelle

Antworten:

669

Tatsächlich können Sie den integrierten Standortdienst nutzen, der eine "Zurück" -API besitzt.

Hier (in 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();
  }
}

Bearbeiten : Wie von @ charith.arumapperuma erwähnt, Locationsollte aus importiert werden, @angular/commondamit die import {Location} from '@angular/common';Zeile wichtig ist.

Amir Sasson
quelle
75
Der Speicherort sollte in älteren Versionen von Angular 2 aus "angle2 / router" importiert werden. In neueren Versionen sollte er aus "@ angle / common" stammen.
charith.arumapperuma
2
Wenn Sie es in das Framework integriert haben, sehe ich keinen Grund, das "native" "window.history.back ();" Dies ist eine HTML5-Funktion ( developer.mozilla.org/en-US/docs/Web/API/Window/history )
Amir Sasson
7
In der offiziellen Angular2-API-Dokumentation Locationheißt es: "Hinweis: Es ist besser, den Router-Dienst zu verwenden, um Routenänderungen auszulösen. Verwenden Sie den Standort nur, wenn Sie mit normalisierten URLs außerhalb des Routings interagieren oder diese erstellen müssen." @ Sasxas Antwort zeigt anscheinend einen Weg, dies Routerzu tun. Die LocationMethode ist jedoch definitiv bequemer. Weiß jemand, warum die RouterMethode korrekter sein könnte als die LocationMethode?
Andrew Willems
2
@ Andrew: Ich habe das Problem festgestellt, dass Sie nicht zweimal zurückkehren können, wenn Sie this.location.back () verwenden. Sie kehren zur ursprünglichen Site zurück.
Johannes
1
@ yt61, nicht sicher, vielleicht Wiederverwendbarkeit? oder wenn Sie von verschiedenen Routen zu einer bestimmten Seite gelangen können, sodass Sie die Route, zu der Sie zurückkehren möchten, nicht im Voraus kennen.
Amir Sasson
111

In der endgültigen Version von Angular 2.x / 4.x finden Sie hier die Dokumente 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
  }
}
Hinrich
quelle
1
Während Sie zum vorherigen Bildschirm zurückkehren, können Sie die eingegebenen Werte beibehalten, ohne ein Objekt im Betrieb zu verwenden.
Vignesh
Wie kann ich eine Animation anzeigen, während location.back () ausgeführt wird?
Schneebasen
48

<button backButton>BACK</button>

Sie können dies in eine Direktive einfügen, die an jedes anklickbare Element angehängt werden kann:

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

Verwendungszweck:

<button backButton>BACK</button>
hansmaad
quelle
das ist großartig!
Rafael de Castro
1
Wenn Sie auf dieser Seite aktualisieren und auf die Schaltfläche klicken, die "this.location.back ()" auslöst, wird nur eine Seitenaktualisierung ausgelöst. Gibt es eine Möglichkeit, mit der das Standortmodul erkennen kann, ob ein vorheriger Pfad vorhanden ist?
Henry LowCZ
gute Arbeit Mann! ;)
elciospy
Denken Sie daran, wenn ein Benutzer direkt zu einer Seite gegangen ist, auf der die Schaltfläche Zurück vorhanden ist, und wenn er auf eine Schaltfläche klickt, wird er gemäß dem Browserverlauf (Plattformverlauf) aus der App auf die vorherige Seite verschoben.
Hastrb
Für zukünftige Leser siehe API-Dokumente
hastrb
23

Getestet mit Angular 5.2.9

Wenn Sie einen Anker anstelle einer Taste verwenden , müssen Sie es machen passive Verbindung mit href="javascript:void(0)"zu Angular Ort Arbeit zu machen.

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>
JavierFuentes
quelle
Ich würde vorschlagen, eine 'clickPreventDefault'-Direktive zu erstellen, anstatt sie zu verwenden javascript:void(0). So etwas wie ... @Directive({ selector: '[clickPreventDefault]' }) export class ClickPreventDefaultDirective { @HostListener("click", ["$event"]) onClick($event: Event) { $event.preventDefault(); } }
BMD
Vielen Dank an @bmd, es ist eine aufwändigere Methode, aber es funktioniert auch. Eine andere funktionierende Lösung ist, kein herf zu verwenden: <a (click)="goBack()"> obwohl auf diese Weise keine HTML-Validatoren übergeben werden.
JavierFuentes
20

Sie können eine routerOnActivate()Methode für Ihre Routenklasse implementieren , die Informationen zur vorherigen Route enthält.

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

Dann können Sie router.navigateByUrl()die aus generierten Daten verwenden und weitergeben ComponentInstruction. Zum Beispiel:

this._router.navigateByUrl(prevInstruction.urlPath);
Sasxa
quelle
Gilt dies noch für Angular 2.1.0?
Smartmouse
1
@smartmouse Ich glaube nicht, es gibt Dokumentation fürrouterOnActivate
Bojan Kogoj
4
Der Link routerOnActivate () in dieser Antwort ist unterbrochen. Dies scheint in der Release-Version nicht der Fall zu sein.
rmcsharry
14

Arbeiten Sie auch für mich, wenn ich wie im Dateisystem zurückkehren muss. PS @angular: "^ 5.0.0"

<button type="button" class="btn btn-primary" routerLink="../">Back</button>
Shevtsiv Andriy
quelle
7
Ich hatte die Hoffnung, dass dies funktionieren würde, aber dies führt zurück zur nächsten darüber liegenden Route - nicht zu der Route, auf der Sie sich befanden, bevor Sie zur Seite navigierten. Gut zu wissen, dass dies existiert, aber wenn Sie mehrere Einstiegspunkte für Ihre Komponente haben, kehrt diese Methode immer nur zu der darüber liegenden Route zurück, nicht zu der, von der Sie stammen.
Scott Byers
Während ich schreibe "wenn ich wie im Dateisystem zurück muss" :) Für mich war dieses Verhalten auch unerwartet.
Shevtsiv Andriy
12

Ich habe eine Schaltfläche erstellt, die ich überall in meiner App wiederverwenden kann.

Erstellen Sie diese Komponente

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

Fügen Sie es dann zu einer beliebigen Vorlage hinzu, wenn Sie eine Zurück-Schaltfläche benötigen.

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

Hinweis: Hierbei wird Winkelmaterial verwendet. Wenn Sie diese Bibliothek nicht verwenden, entfernen Sie das mat-buttonund color.

Todd Skelton
quelle
Funktioniert dieser Ansatz jedoch mit benannten Router-Steckdosen? Angenommen, ich habe mehrere auf der Seite und möchte nur auf eine davon zurückgreifen. Würde dies funktionieren?
9.
Sie müssen für diese Situation einen anderen Ansatz verwenden. Wenn Sie dieselbe Zurück-Taste in zwei verschiedenen Router-Ausgängen hatten, werden wahrscheinlich beide dasselbe tun und zum letzten Router-Ausgang zurückkehren, der geändert wurde.
Todd Skelton
Für benannte Verkaufsstellen stellte ich fest, dass dieser Ansatz funktionierte: this.router.navigate (['../'], {relativeTo: this.route})
15.
Wie verwende ich diese Komponente in einer anderen Komponente?
RN Kushwaha
12

Nach all diesen tollen Antworten hoffe ich, dass meine Antwort jemanden findet und ihm hilft. Ich habe einen kleinen Dienst geschrieben, um den Verlauf der Route zu verfolgen. Hier kommt's.

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;
  }
}
Anjil Dhamala
quelle
Nachdem ich mehr oder weniger alle Lösungen ausprobiert habe, finde ich, dass dies der konsequentere Weg ist, dies zu tun
A. D'Alfonso
Was ist, wenn ich die Seite über einen bestimmten Link öffne und möchte, dass sie zu der Seite im Seitenbaum zurückkehrt?
Ivan
8

So wie ich es beim Navigieren zu einer anderen Seite gemacht habe, fügen Sie einen Abfrageparameter hinzu, indem Sie den aktuellen Speicherort übergeben

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

Lesen Sie diesen Abfrageparameter in Ihrer Komponente

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

Wenn returnUrl vorhanden ist, aktivieren Sie die Zurück-Schaltfläche und wenn der Benutzer auf die Zurück-Schaltfläche klickt

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

Dies sollte in der Lage sein, zur vorherigen Seite zu navigieren. Anstatt location.back zu verwenden, ist die oben beschriebene Methode meiner Meinung nach sicherer. Betrachten Sie den Fall, in dem der Benutzer direkt auf Ihrer Seite landet. Wenn er die Zurück-Taste mit location.back drückt, wird der Benutzer zur vorherigen Seite weitergeleitet, die nicht Ihre Webseite ist.

Puneeth Rai
quelle
Sie müssen ActivatedRoute importieren und anstelle von Router für das queryParams-Abonnement verwenden (z. B. this.route.queryParams.subscribe), aber ansonsten scheint es zu funktionieren!
Stephen Kaiser
für mich funktioniert es gut mit Router selbst in Winkel 4
Puneeth Rai
1
Beste Antwort, aber in Angular 5 (bis zu x?) Müssen Sie ein Objekt von "ActivatedRoute" einfügen und queryParams für dieses Objekt verwenden, wie Stephen Kaiser bereits sagte.
Satria
8

In RC4:

import {Location} from '@angular/common';
Tomasz Bielawa
quelle
3

Um zurück zu gehen, ohne die Seite zu aktualisieren, können wir in HTML wie unten Javascript tun : history.back ()

<a class="btn btn-danger" href="javascript:history.back()">Go Back</a>
Singhak
quelle
Ich würde empfehlen, Locationstattdessen Service zu verwenden. offizielle API
hastrb
2

Seit Beta 18:

import {Location} from 'angular2/platform/common';

Albert
quelle
2

Eine andere Lösung

window.history.back();

Džan Operta
quelle
Funktioniert für mich location.back () funktioniert auch, aber ich kompiliere nicht mit --prod
Alex