Як повернути останню сторінку


366

Чи є розумний спосіб повернути останню сторінку в Angular 2?

Щось на зразок

this._router.navigate(LASTPAGE);

Наприклад, на сторінці C є Go Backкнопка,

  • Сторінка A -> Сторінка C, клацніть її, поверніться до сторінки А.

  • Сторінка B -> Сторінка C, клацніть її, поверніться до сторінки B.

Чи має маршрутизатор цю інформацію про історію?

Відповіді:


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
Місце розташування слід імпортувати з "angular2 / router" у старших випусках програми Angular 2. У новіших випусках воно повинно бути з "@ angular / common".
charith.arumapperuma

2
Якщо у вас це вбудовано в рамках, я не бачу причин використовувати "рідне" "window.history.back ();" що є функцією HTML5 ( developer.mozilla.org/en-US/docs/Web/API/Window/history )
Амір Сассон

7
Для чого варто офіційна документація Angular2 API для Locationдержав: "Примітка: краще використовувати послугу маршрутизатора для запуску змін маршруту. Використовуйте розташування лише в тому випадку, якщо вам потрібно взаємодіяти або створювати нормалізовані URL-адреси поза маршрутом." @ Відповідь Сасса, очевидно, показує спосіб використовувати Routerце. Однак Locationметод, безумовно, є більш зручним. Хтось знає, чому Routerметод може бути більш правильним, ніж Locationметод?
Ендрю Віллемс

2
@Andrew: У мене виникла проблема, що ви не можете повернутися два рази назад, якщо ви використовуєте this.location.back (). Ви перейдете на початковий сайт.
Йоганнес

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
Під час повернення до попереднього екрану ми можемо зберігати введені значення вводу, не використовуючи об’єкт, що обслуговується.
Виньєш

Як показати анімацію назад під час виконання 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 ()", це просто запустить оновлення сторінки. Чи є спосіб, що модуль Location може виявити, чи існує попередній шлях?
Генрі Лоукоз

добрий чоловік! ;)
elciospy

Майте на увазі, якщо користувач перейшов безпосередньо на сторінку, де існує кнопка Назад, і якщо він натисне на кнопку .., він буде викинутий із програми на попередню сторінку відповідно до історії браузера (платформи).
hastrb

Для майбутніх читачів дивіться документи API
hastrb

23

Перевірено з кутовим 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 Validators.
Хав'єр Фуентес

20

Ви можете реалізувати routerOnActivate()метод у своєму класі маршруту, він надасть інформацію про попередній маршрут.

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

Тоді ви можете використовувати router.navigateByUrl()та передавати дані, згенеровані з ComponentInstruction. Наприклад:

this._router.navigateByUrl(prevInstruction.urlPath);

Чи все ще справедливо для кутових 2.1.0?
smartmouse

1
@smartmouse Я не думаю, що так, є документація дляrouterOnActivate
Bojan Kogoj

4
Посилання routerOnActivate () у цій відповіді порушено. Здається, це не спосіб зробити це у версії випуску.
rmcsharry

14

Також працюйте для мене, коли мені потрібно повернутися назад, як у файловій системі. PS @angular: "^ 5.0.0"

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

7
Я сподівався, що це спрацює, але це повернеться до наступного маршруту над ним - не до маршруту, на якому ви були, перш ніж перейти на сторінку. Добре знати, що це існує, але якщо у вас є кілька точок входу для вашого компонента, цей метод повернеться лише до маршруту над ним, а не там, звідки ви родом.
Скотт Байєрс

Коли я пишу "коли мені потрібно повернутися назад, як у файловій системі" :) Для мене така поведінка також була несподіваною.
Шевців Андрій

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>

Примітка. Для цього використовується кутовий матеріал, якщо ви не використовуєте цю бібліотеку, тоді видаліть mat-buttonі color.


Чи працює цей підхід із названими маршрутизаторами? Скажіть, у мене на сторінці декілька, і я хочу лише повернутись на одну з них, чи не вдасться це?
RRD

Для цієї ситуації вам доведеться використовувати інший підхід. Якщо у вас була одна і та ж кнопка "назад" у двох розетках маршрутизатора, вони, ймовірно, обидва роблять те саме і повертаються до останньої розетки маршрутизатора, яка була змінена.
Тодд Скелтон

Для названих точок, я виявив , що цей підхід спрацював: this.router.navigate ([ '../'], {relativeTo: this.route})
RRD

Як використовувати цей компонент всередині іншого компонента?
Р. Н.

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

Спробувавши більш-менш усі рішення, я вважаю, що цей спосіб є більш послідовним
А.

Що робити, якщо я відкрию сторінку на певному посиланні і хочу, щоб вона повернулася до сторінки, що знаходиться у дереві сторінки?
Іван

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, він перенаправить користувача на попередню сторінку, яка не буде вашою веб-сторінкою.


Потрібно імпортувати ActivateRoute і використовувати це замість маршрутизатора для підписки queryParams (наприклад, this.route.queryParams.subscribe), але в іншому випадку, здається, працює!
Стівен Кайзер

для мене це добре працює з самим маршрутизатором навіть у кутовому 4
Puneeth Rai

1
Найкраща відповідь, але в Angular 5 (до x?) Вам потрібно вставити об'єкт "ActivateRoute" і використовувати queryParams на цьому об'єкті, як уже зазначив Стівен Кайзер.
Satria


3

Щоб повернутися назад, не оновлюючи сторінку, ми можемо робити в html, як нижче, javascript: history.back ()

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

Я б рекомендував Locationскоріше використовувати сервіс. офіційний API
hastrb



Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.