Come tornare all'ultima pagina


369

Esiste un modo intelligente per tornare all'ultima pagina in Angular 2?

Qualcosa di simile a

this._router.navigate(LASTPAGE);

Ad esempio, la pagina C ha un Go Backpulsante,

  • Pagina A -> Pagina C, fare clic su di essa, tornare alla pagina A.

  • Pagina B -> Pagina C, fare clic su di essa, tornare alla pagina B.

Il router ha queste informazioni sulla cronologia?

Risposte:


673

In realtà puoi usufruire del servizio di localizzazione integrato, che possiede un'API "Indietro".

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

Modifica : come menzionato da @ charith.arumapperuma Locationdovrebbe essere importato da @angular/commoncosì la import {Location} from '@angular/common';linea è importante.


75
La posizione deve essere importata da "angular2 / router" nelle versioni precedenti di Angular 2. Nelle versioni più recenti, dovrebbe essere da "@ angular / common".
charith.arumapperuma,

2
Se lo hai incorporato nel framework, non vedo alcun motivo per usare il "nativo" "window.history.back ();" che è una funzione HTML5 ( developer.mozilla.org/en-US/docs/Web/API/Window/history )
Amir Sasson

7
Per quello che vale, la documentazione ufficiale dell'API di Angular2 per gli Locationstati: "Nota: è meglio usare il servizio Router per innescare le modifiche del percorso. Utilizzare Posizione solo se è necessario interagire con o creare URL normalizzati al di fuori del routing." La risposta di @Sasxa sembra mostrare un modo per usarlo Router. Tuttavia, il Locationmetodo è sicuramente più conveniente. Qualcuno sa perché il Routermetodo potrebbe essere più corretto del Locationmetodo?
Andrew Willems,

2
@Andrew: ho riscontrato il problema, che non puoi tornare indietro due volte, se usi this.location.back (). Tornerai al sito iniziale.
Johannes,

1
@ yt61, non sono sicuro, forse riutilizzabilità? o se riesci ad arrivare a una pagina specificata da vari percorsi, quindi non conosci in anticipo il percorso a cui tornare.
Amir Sasson,

111

Nella versione finale di Angular 2.x / 4.x: ecco i documenti 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
Durante la navigazione alla schermata precedente è possibile conservare i valori immessi in input senza utilizzare un oggetto in servizio.
Vignesh,

Come mostrare l'animazione durante l'esecuzione di location.back ()?
Snow Bases

48

<button backButton>BACK</button>

Puoi inserirlo in una direttiva, che può essere collegata a qualsiasi elemento cliccabile:

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

Uso:

<button backButton>BACK</button>

è fantastico!
Rafael de Castro,

1
Se aggiorni su questa pagina e fai clic sul pulsante che attiva "this.location.back ()", si attiverà semplicemente un aggiornamento della pagina. Esiste un modo in cui il modulo Location può rilevare se esiste un percorso precedente?
Henry LowCZ

buon lavoro amico! ;)
elciospy il

Tieni presente che se un utente è andato direttamente a una pagina in cui esiste il pulsante Indietro e se fa clic su un pulsante ... verrà eliminato dall'app alla pagina precedente in base alla cronologia del browser (piattaforma).
hastrb,

Per i lettori futuri, guarda i documenti API
hastrb

24

Testato con Angolare 5.2.9

Se si utilizza un ancoraggio al posto di un pulsante è necessario effettuare un collegamento passivo con href="javascript:void(0)"per rendere il lavoro angolare Posizione.

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>

Suggerirei di creare una direttiva "clickPreventDefault" anziché utilizzare javascript:void(0). Qualcosa del tipo ... @Directive({ selector: '[clickPreventDefault]' }) export class ClickPreventDefaultDirective { @HostListener("click", ["$event"]) onClick($event: Event) { $event.preventDefault(); } }
bmd

Grazie @bmd, è un modo più elaborato ma funziona anche. Un'altra soluzione funzionante è non usare herf: <a (click)="goBack()"> sebbene in questo modo non passi i validatori HTML.
JavierFuentes,

20

È possibile implementare il routerOnActivate()metodo sulla classe del percorso, fornirà informazioni sul percorso precedente.

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

Quindi è possibile utilizzare router.navigateByUrl()e trasmettere i dati generati da ComponentInstruction. Per esempio:

this._router.navigateByUrl(prevInstruction.urlPath);

È ancora valido per Angular 2.1.0?
smartmouse,

1
@smartmouse Non credo, c'è documentazione perrouterOnActivate
Bojan Kogoj,

4
Il collegamento routerOnActivate () in questa risposta è interrotto. Sembra che questo non sia il modo di farlo nella versione di rilascio.
rmcsharry,

14

Lavora anche per me quando devo tornare indietro come nel file system. PS @angular: "^ 5.0.0"

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

7
Speravo che avrebbe funzionato, ma questo torna al percorso successivo sopra di esso - non al percorso che stavi percorrendo prima di navigare nella pagina. Buono a sapersi che esiste, ma se hai più punti di ingresso per il tuo componente, questo metodo tornerà sempre al percorso sopra di esso, non da dove hai avuto origine.
Scott Byers,

Mentre scrivo "quando devo tornare indietro come nel file system" :) Anche per me questo comportamento è stato inaspettato.
Shevtsiv Andriy,

12

Ho creato un pulsante che posso riutilizzare ovunque sulla mia app.

Crea questo componente

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

Quindi aggiungilo a qualsiasi modello quando hai bisogno di un pulsante Indietro.

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

Nota: questo utilizza il materiale angolare, se non si utilizza quella libreria, rimuovere mat-buttone color.


Questo approccio funziona con le prese router denominate? Diciamo che ne ho diversi sulla pagina e voglio solo tornare su uno di questi, funzionerebbe?
RRD

Dovrai usare un approccio diverso per quella situazione. Se hai avuto lo stesso pulsante Indietro in due diverse prese del router, probabilmente entrambe faranno la stessa cosa e torneranno all'ultima presa del router che è stata modificata.
Todd Skelton,

Per le prese di nome, ho scoperto che questo approccio ha funzionato: this.router.navigate ([ '../'], {relativeTo: this.route})
RRD

Come utilizzare questo componente all'interno di un altro componente?
RN Kushwaha,

12

Dopo tutte queste fantastiche risposte, spero che la mia risposta trovi qualcuno e li aiuti. Ho scritto un piccolo servizio per tenere traccia della cronologia dei percorsi. Eccolo.

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

Dopo aver provato più o meno tutte le soluzioni, trovo che questo sia il modo più coerente per farlo
A. D'Alfonso

Cosa succede se apro la pagina su un determinato link e voglio che torni alla pagina che nella struttura ad albero della pagina?
Ivan,

8

Il modo in cui l'ho fatto mentre navigavo su una pagina diversa aggiunge un parametro di query passando la posizione corrente

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

Leggi questo parametro di query nel tuo componente

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

Se returnUrl è presente abilitare il pulsante Indietro e quando l'utente fa clic sul pulsante Indietro

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

Questo dovrebbe essere in grado di navigare alla pagina precedente. Invece di usare location.back ritengo che il metodo sopra sia più sicuro, considera il caso in cui l'utente atterra direttamente alla tua pagina e se preme il pulsante indietro con location.back reindirizzerà l'utente alla pagina precedente che non sarà la tua pagina web.


È necessario importare ActivatedRoute e utilizzarlo al posto del router sull'abbonamento queryParams (ad es. This.route.queryParams.subscribe), ma per il resto sembra funzionare!
Stephen Kaiser,

per me funziona bene con il router stesso anche nell'angolo 4
Puneeth Rai,

1
La migliore risposta, ma in Angular 5 (fino a x?) È necessario iniettare un oggetto di "ActivatedRoute" e utilizzare queryParams su questo oggetto, come già affermato da Stephen Kaiser.
Satria,


3

Per tornare indietro senza aggiornare la pagina, possiamo fare in html come sotto javascript: history.back ()

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

Consiglierei Locationinvece di usare il servizio. API ufficiale
hastrb

2

Dalla beta 18:

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



2

Un'altra soluzione

window.history.back();


Funziona anche per me location.back () funziona ma non compilo con --prod
Alex il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.