我们使用下面的代码将Router注入到应用Component的构造函数中,然后调用它的navigate方法。这种思路只能实现SPA应用的静态路由跳转。import{Router}from'@angular/router'@Component({...})exportclassUserDetailComponent{constructor(privaterouter:Router){}back():void{this.router.navigate('/users')}}我们可以使用相对路由的思想。两个点..代表相对路由:back():void{this.router.navigate("..");}但是,这仅在列表组件注册为具有空路径的子组件时有效,就像完成的一样在下面的路由配置中。constroutes:Routes=[{path:'users',component:UsersComponent,children:[{path:'',component:UserListComponent},{path:'active',component:ActiveUsersComponent},{path:':id'},component:UserDetailComponent},],},{path:'**',redirectTo:'users'},]否则,您必须将点附加到定位的子路由(例如../list)。实际上,这种方法只是在路由层次结构中向上导航一个级别。绝对路径和相对路径都不一定返回到用户之前去过的地方。它们提供静态导航,并且在开发过程中已经很清楚相应导航的最终位置。因此,即使那是用户在导航到详细信息视图之前所在的位置,也不容易返回到/users/active。我们需要找到另一种解决方案来促进这种行为。浏览器的后退按钮基于浏览器历史记录。它有一个JavaScriptAPI,我们可以使用它在Angular应用程序中动态地来回导航。事实上,Angular甚至提供了Location服务作为平台抽象。该服务有一个back()方法,它完全符合我们的要求:它在浏览器的历史记录中向后导航一步。我们可以将服务注入细节组件或任何中间组件,并在单击按钮时调用它::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'})exportclassNavigationService{privatehistory:string[]=[]constructor(privaterouter:Router,privatelocation:Location){this.router.events.subscribe((event)=>{if(eventinstanceofNavigationEnd){this.history.push(event.urlAfterRedirects)}})}back():void{this.history.pop()if(this.history.length>0){this.location.back()}else{this.router.navigateByUrl('/')}}}本文完整源码已经托管在StackBlitz上,链接如下。
