Jak wrócić na ostatnią stronę


366

Czy istnieje sprytny sposób na powrót do ostatniej strony w Angular 2?

Coś jak

this._router.navigate(LASTPAGE);

Na przykład strona C ma Go Backprzycisk,

  • Strona A -> Strona C, kliknij ją, wróć do strony A.

  • Strona B -> Strona C, kliknij ją, wróć do strony B.

Czy router ma tę historię?

Odpowiedzi:


669

W rzeczywistości możesz skorzystać z wbudowanej usługi lokalizacji, która posiada interfejs API „Wstecz”.

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

Edytować : Jak wspomniano przez @ charith.arumapperuma Locationnależy zaimportować z, @angular/commonwięc import {Location} from '@angular/common';linia jest ważna.


75
Lokalizacja powinna zostać zaimportowana z „angular2 / router” w starszych wersjach Angular 2. W nowszych wersjach powinna być z „@ angular / common”.
charith.arumapperuma

2
Jeśli masz to wbudowane w ramach, nie widzę żadnego powodu, aby używać „native” „window.history.back ();” która jest funkcją HTML5 ( developer.mozilla.org/en-US/docs/Web/API/Window/history )
Amir Sasson

7
Jeśli chodzi o to, co jest warte, oficjalna dokumentacja Angular2 API dla Locationstanów stwierdza: „Uwaga: lepiej jest użyć usługi routera, aby wywołać zmiany trasy. Użyj lokalizacji tylko wtedy, gdy musisz wchodzić w interakcje lub tworzyć znormalizowane adresy URL poza routingiem”. Odpowiedź @ Sasxa najwyraźniej pokazuje sposób, aby Routerto zrobić. Jednak Locationmetoda jest zdecydowanie wygodniejsza. Czy ktoś wie, dlaczego Routermetoda może być bardziej poprawna niż Locationmetoda?
Andrew Willems,

2
@Andrew: napotkałem problem polegający na tym, że nie możesz wrócić dwa razy, jeśli użyjesz this.location.back (). Wrócisz do początkowej strony.
Johannes,

1
@ yt61, nie jestem pewien, może ponowne użycie? lub jeśli możesz dotrzeć do określonej strony z różnych tras, więc nie znasz z góry trasy, do której chcesz wrócić.
Amir Sasson

111

W ostatecznej wersji Angular 2.x / 4.x - oto dokumentacja 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
Wracając do poprzedniego ekranu, możemy zachować wprowadzone wartości bez użycia obiektu w serwisie.
Vignesh

Jak wyświetlić animację z powrotem podczas wykonywania location.back ()?
Snow Bases

48

<button backButton>BACK</button>

Możesz umieścić to w dyrektywie, którą można dołączyć do dowolnego klikalnego elementu:

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

Stosowanie:

<button backButton>BACK</button>

to cudownie!
Rafael de Castro,

1
Jeśli odświeżysz tę stronę i klikniesz przycisk, który wyzwala „this.location.back ()”, spowoduje to tylko odświeżenie strony. Czy jest jakiś sposób, aby moduł lokalizacji mógł wykryć, czy istnieje poprzednia ścieżka?
Henry LowCZ

dobra robota człowieku! ;)
elciospy

Pamiętaj, że jeśli użytkownik przejdzie bezpośrednio na stronę, na której istnieje przycisk Wstecz, a jeśli kliknie przycisk .., zostanie on wyrzucony z aplikacji na poprzednią stronę zgodnie z historią przeglądarki (platformy).
hastrb

Dla przyszłych czytelników
zapoznaj się z

23

Testowane z użyciem kątownika 5.2.9

Jeśli używasz kotwicę zamiast przycisku musisz zrobić to pasywny związek z href="javascript:void(0)"aby kątowa miejsce pracy.

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>

Sugerowałbym utworzenie dyrektywy „clickPreventDefault” zamiast używania javascript:void(0). Coś w stylu ... @Directive({ selector: '[clickPreventDefault]' }) export class ClickPreventDefaultDirective { @HostListener("click", ["$event"]) onClick($event: Event) { $event.preventDefault(); } }
bmd

Dziękuję @bmd, jest to bardziej skomplikowany sposób, ale także działa. Innym działającym rozwiązaniem jest nieużywanie herf: <a (kliknięcie )="goBack()"> chociaż w ten sposób nie przechodzą walidatory HTML.
JavierFuentes

20

Możesz zaimplementować routerOnActivate()metodę na swojej klasie trasy, która dostarczy informacji o poprzedniej trasie.

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

Następnie możesz używać router.navigateByUrl()i przekazywać dane wygenerowane z ComponentInstruction. Na przykład:

this._router.navigateByUrl(prevInstruction.urlPath);

Czy nadal obowiązuje to dla Angular 2.1.0?
smartmouse

1
@smartmouse Nie sądzę, istnieje dokumentacjarouterOnActivate
Bojan Kogoj

4
Link routerOnActivate () w tej odpowiedzi jest uszkodzony. Wydaje się, że nie jest to sposób, aby to zrobić w wersji.
rmcsharry

14

Pracuj także dla mnie, gdy muszę cofnąć się jak w systemie plików. PS @ prostokątny: „^ 5.0.0”

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

7
Miałem nadzieję, że to zadziała, ale przenosi się z powrotem do następnej Trasy nad nią - nie do trasy, którą byłeś przed przejściem do strony. Dobrze wiedzieć, że istnieje, ale jeśli masz wiele punktów wejścia dla swojego komponentu, ta metoda zawsze wróci tylko do trasy nad nią, a nie od miejsca, z którego się wywodzisz.
Scott Byers,

Kiedy piszę „kiedy muszę wrócić jak w systemie plików” :) Dla mnie to zachowanie było również nieoczekiwane.
Shevtsiv Andriy

12

Zrobiłem przycisk, którego mogę użyć ponownie w dowolnym miejscu w mojej aplikacji.

Utwórz ten komponent

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

Następnie dodaj go do dowolnego szablonu, gdy potrzebujesz przycisku Wstecz.

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

Uwaga: używa to materiału kątowego, jeśli nie korzystasz z tej biblioteki, usuń mat-buttoni color.


Czy to podejście działa jednak z nazwanymi gniazdami routera? Powiedzmy, że mam kilka na stronie i chcę wrócić tylko na jednym z nich, czy to zadziała?
RRD

W tej sytuacji będziesz musiał zastosować inne podejście. Jeśli miałeś ten sam przycisk powrotu w dwóch różnych gniazdach routera, prawdopodobnie oba zrobią to samo i wrócą do ostatniego gniazda routera, które zostało zmienione.
Todd Skelton

Dla wymienionych wylotów, okazało się, że takie podejście działa: this.router.navigate ([ '../'], {relativeTo: this.route})
rrD

Jak korzystać z tego komponentu w innym komponencie?
RN Kushwaha

12

Po tych wszystkich niesamowitych odpowiedziach mam nadzieję, że moja odpowiedź znajdzie kogoś i pomoże mu. Napisałem małą usługę, aby śledzić historię trasy. Oto jest.

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

Po wypróbowaniu mniej więcej wszystkich rozwiązań, uważam, że jest to bardziej spójny sposób
A. D'Alfonso

Co się stanie, jeśli otworzę stronę pod danym linkiem i chcę, aby wróciła do strony tej w drzewie strony?
Ivan

8

Sposób, w jaki to zrobiłem, przechodząc do innej strony, dodaje parametr zapytania, przekazując bieżącą lokalizację

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

Przeczytaj ten parametr zapytania w swoim komponencie

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

Jeśli returnUrl jest obecny, włącz przycisk Wstecz i gdy użytkownik kliknie przycisk Wstecz

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

Powinno to umożliwić przejście do poprzedniej strony. Zamiast korzystać z location.back uważam, że powyższa metoda jest bezpieczniejsza, rozważ przypadek, w którym użytkownik bezpośrednio wyląduje na Twojej stronie, a jeśli naciśnie przycisk Wstecz z location.back, przekieruje użytkownika do poprzedniej strony, która nie będzie Twoją stroną internetową.


Musisz zaimportować ActivatedRoute i użyć go zamiast routera w subskrypcji queryParams (np. This.route.queryParams.subscribe), ale poza tym wydaje się, że działa!
Stephen Kaiser,

dla mnie działa dobrze z samym routerem nawet w kanciastym 4
Puneeth Rai

1
Najlepsza odpowiedź, ale w Angular 5 (do x?) Musisz wstrzyknąć obiekt „ActivatedRoute” i użyć queryParams na tym obiekcie, jak już stwierdził Stephen Kaiser.
Satria


3

Aby wrócić bez odświeżania strony, możemy to zrobić w html jak poniżej javascript: history.back ()

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

LocationZamiast tego poleciłbym skorzystanie z usługi. oficjalne API
hastrb

2

Od wersji beta 18:

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



2

Inne rozwiązanie

window.history.back();


Działa dla mnie location.back () również działa, ale nie kompiluję z --prod
Alex
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.