咱们应用上面的代码,将 Router 注入到应用程序 Component 的构造函数里,而后再调用其 navigate 办法,这种思路只能实现 SPA 利用间的动态路由跳转。

import { Router } from '@angular/router'@Component({...})export class UserDetailComponent {  constructor(private router: Router) {}  back(): void {    this.router.navigate('/users')  }}

咱们能够应用绝对路由的思路。

两个点号 .. 代表绝对路由:

back(): void {    this.router.navigate("..");}

然而,这仅在列表组件注册为具备空门路的子组件时才无效,就像在上面的路由配置中所做的那样。

const routes: Routes = [  {    path: 'users',    component: UsersComponent,    children: [      { path: '', component: UserListComponent },      { path: 'active', component: ActiveUsersComponent },      { path: ':id', component: UserDetailComponent },    ],  },  { path: '**', redirectTo: 'users' },]

否则,您必须将点附加到定位的子路由(例如 ../list)。 实际上,这种办法只是在路由层次结构中向上导航一层。

绝对路径和相对路径都不肯定会返回到用户之前去过的中央。 它们提供动态导航,并且在开发过程中曾经很分明相应的导航将在何处完结。 因而,即便这是用户在导航到详细信息视图之前所在的地位,也不容易返回到 /users/active. 咱们须要找到另一种解决方案来促成这种行为。

浏览器的后退按钮基于浏览器历史记录(browser history)。它有一个 JavaScript API,咱们能够应用它在咱们的 Angular 应用程序中动静地来回导航。 事实上,Angular 甚至提供 Location 服务作为平台形象。

该服务有一个 back() 办法,它完全符合咱们的要求:它在浏览器的历史记录中向后导航一步。 咱们能够将服务注入细节组件或任何两头组件,并在单击按钮时调用它:

import { Location } from '@angular/common'@Component({...})export class UserDetailComponent {  constructor(private location: Location) {}  back(): void {    this.location.back()  }}

须要留神的是,有一种极其状况:如果应用程序是在关上浏览器或新选项卡后在详细信息路由器上启动的,那么历史记录中将没有可返回的条目。

在这种状况下,location.back() 会将用户从 Angular 应用程序中抛出。 也没有用于间接查看浏览器历史记录的 API,因为这可能会带来平安问题,但咱们依然有方法解决这个问题。

咱们将创立一个用于包装后退导航的服务。 在那里,咱们还将监听 NavigationEnd 类型的路由器事件,以治理特定于应用程序的导航历史记录。 当初,如果在从堆栈中弹出以后 URL 后历史依然蕴含条目,咱们能够平安地导航回来。 否则咱们将回退到应用程序根目录:

import { Injectable } from '@angular/core'import { Location } from '@angular/common'import { Router, NavigationEnd } from '@angular/router'@Injectable({ providedIn: 'root' })export class NavigationService {  private history: string[] = []  constructor(private router: Router, private location: Location) {    this.router.events.subscribe((event) => {      if (event instanceof NavigationEnd) {        this.history.push(event.urlAfterRedirects)      }    })  }  back(): void {    this.history.pop()    if (this.history.length > 0) {      this.location.back()    } else {      this.router.navigateByUrl('/')    }  }}

本文残缺的源代码曾经托管到了 StackBlitz 上,链接如下。