วิธีการย้อนกลับหน้าสุดท้าย


366

มีวิธีที่ชาญฉลาดในการย้อนกลับหน้าสุดท้ายใน Angular 2 หรือไม่?

สิ่งที่ต้องการ

this._router.navigate(LASTPAGE);

ตัวอย่างเช่นหน้า C มีGo Backปุ่ม

  • หน้า A -> หน้า C คลิกที่มันกลับไปที่หน้า A

  • หน้า 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 / เราเตอร์" ในรุ่นที่เก่ากว่าของ Angular 2 ในรุ่นที่ใหม่กว่านั้นควรมาจาก "@ angular / common"
charith.arumapperuma

2
หากคุณมีมันอยู่ในกรอบฉันไม่เห็นเหตุผลที่จะใช้ "native" "window.history.back ();" ซึ่งเป็นคุณลักษณะ HTML5 ( developer.mozilla.org/en-US/docs/Web/API/Window/history )
Amir Sasson

7
สำหรับสิ่งที่มีค่าควรใช้เอกสาร Angular2 API อย่างเป็นทางการสำหรับLocationรัฐ: "หมายเหตุ: ควรใช้บริการเราเตอร์เพื่อทริกเกอร์การเปลี่ยนเส้นทางใช้ที่ตั้งเฉพาะในกรณีที่คุณต้องการโต้ตอบหรือสร้าง URL ปกตินอกการกำหนดเส้นทาง" คำตอบ @ Sasxaเห็นได้ชัดว่าแสดงวิธีการใช้Routerสิ่งนี้ อย่างไรก็ตามLocationวิธีนี้สะดวกกว่าแน่นอน ไม่มีใครรู้ว่าทำไมRouterวิธีการอาจถูกต้องมากกว่าLocationวิธีการหรือไม่
Andrew Willems

2
@Andrew: ฉันพบปัญหาที่คุณไม่สามารถย้อนกลับสองครั้งหากคุณใช้ this.location.back () คุณจะกระโดดกลับไปที่ไซต์เริ่มต้น
โยฮันเนส

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

วิธีการแสดงภาพเคลื่อนไหวกลับในขณะที่ 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

23

ทดสอบกับ 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

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
ฉันหวังว่ามันจะใช้งานได้ แต่สิ่งนี้จะย้ายกลับไปยังเส้นทางถัดไปที่อยู่ด้านบนไม่ใช่เส้นทางที่คุณใช้ก่อนที่จะไปยังหน้าเว็บ เป็นการดีที่จะทราบว่ามีสิ่งนี้อยู่ แต่ถ้าคุณมีจุดเข้าใช้หลายจุดสำหรับส่วนประกอบของคุณวิธีนี้จะย้อนกลับไปที่เส้นทางด้านบนเท่านั้นไม่ใช่จากที่ที่คุณมา
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>

หมายเหตุ: นี่คือการใช้วัสดุเชิงมุมถ้าคุณไม่ได้ใช้ห้องสมุดที่แล้วเอาและmat-buttoncolor


วิธีนี้ใช้ได้กับเต้ารับเราเตอร์ที่มีชื่อหรือไม่ ว่าฉันมีหลายหน้าและต้องการกลับไปหนึ่งในพวกเขาจะทำงานได้หรือไม่
rrd

คุณจะต้องใช้วิธีการอื่นสำหรับสถานการณ์นั้น หากคุณมีปุ่มย้อนกลับที่เหมือนกันในสองเต้ารับที่แตกต่างกันพวกเขาอาจจะทำสิ่งเดียวกันและกลับไปที่เต้ารับเราเตอร์ล่าสุดที่มีการเปลี่ยนแปลง
Todd Skelton

สำหรับร้านค้าที่มีชื่อฉันพบว่าวิธีการนี้ใช้งานได้: this.router.navigate (['../'], {relativeTo: this.route})
rrd

วิธีใช้ส่วนประกอบนี้ภายในองค์ประกอบอื่น
RN Kushwaha

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

จะเกิดอะไรขึ้นถ้าฉันเปิดหน้าในลิงค์ที่ต้องการและฉันต้องการให้มันกลับไปที่หน้าในแผนผังหน้า?
อีวาน

8

วิธีที่ฉันทำในขณะที่นำทางไปยังหน้าอื่น ๆ ให้เพิ่มพารามิเตอร์แบบสอบถามด้วยการส่งผ่านตำแหน่งปัจจุบัน

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

อ่าน param แบบสอบถามนี้ในองค์ประกอบของคุณ

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

หาก returnUrl อยู่เปิดใช้งานปุ่มย้อนกลับและเมื่อผู้ใช้คลิกปุ่มย้อนกลับ

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

สิ่งนี้จะสามารถนำทางไปยังหน้าก่อนหน้า แทนที่จะใช้ location.back ฉันรู้สึกว่าวิธีการข้างต้นนั้นปลอดภัยกว่าพิจารณากรณีที่ผู้ใช้เชื่อมโยงไปยังหน้าของคุณโดยตรงและถ้าเขากดปุ่มย้อนกลับด้วย location.back มันจะเปลี่ยนเส้นทางผู้ใช้ไปยังหน้าก่อนหน้าซึ่งจะไม่ใช่หน้าเว็บของคุณ


จำเป็นต้องนำเข้า ActivatedRoute และใช้แทน Router ในการสมัครสมาชิก queryParams (เช่น this.route.queryParams.subscribe) แต่ดูเหมือนว่าจะใช้งานได้!
สตีเฟ่นไกเซอร์

สำหรับฉันมันทำงานได้ดีกับเราเตอร์ตัวเองแม้ในเชิงมุม 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



2

ทางออกอื่น

window.history.back();


ทำงานได้สำหรับฉัน location.back () ยังใช้งานได้ แต่ฉันไม่ได้คอมไพล์ด้วย --prod
Alex
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.