我有一个 Angular 4 应用程序,可以使用 @angular/router 中的路由器进行导航
导航结构相当简单,包括:
/products
/products/:productId
/products/:productId/edit-details
/products/:productId/edit-images
etc
路由器模块一切正常。
我遇到的问题是保存数据后的浏览器后退按钮 - 给出以下场景:
执行上述操作后,用户单击浏览器后退按钮。我认为大多数用户会期望“后退”按钮将他们带到“产品列表”的一个级别,但实际上它会将他们带回“/products/5/edit-details”屏幕,因为这是他们所在的最后一条路线。
这可能是网站与单页应用程序中的预期行为之间的一点冲突。 SPA 的外观和感觉更像是一个应用程序,而不是传统的网站。在大多数应用程序中,设备后退按钮用作“向上/后退”按钮(例如,在我的手机上使用联系人应用程序,您会看到:联系人列表 -> 联系人详细信息 -> 编辑联系人 -> 保存 [带您查看联系人详细信息] ->按“后退”按钮会将用户带到“联系人列表”,而不是返回“编辑联系人”屏幕,因此用户已被告知可以通过设备上的“后退”按钮实现此行为。
我尝试过使用:
this.location.back();
而不是
this.router.navigate(['../'], { relativeTo: this.route });
用户点击保存后
这确实部分实现了我想要的,但是这为“转发”按钮留下了一个不需要的选项 - 绕过路由器模块似乎也有点错误。
删除后这种行为尤其烦人: 例如如果您转到“/products/:productId/edit-images/:imageId”并删除图像,则不存在的路线仍保留在“返回历史记录”中
我也尝试过使用“skipLocationChange”,但这并没有达到预期的效果,就像我在链接中使用skipLocationChange进入“编辑详细信息”屏幕,然后用户按下后退按钮然后绕过:productId 屏幕并直接进入“/products”列表
有什么建议吗?
浏览器存储一堆 URL。只有当 URL 更改并存储在浏览器的导航历史记录中时,您才能导航回之前的路线。 Angular 以编程方式更改路由,而不实际将 URL 存储在历史记录中。您可以在浏览器的历史记录中验证这一点。
我非常喜欢这个解决方案,因为它可以扩展到全球水平。 创建一个导航历史服务,订阅路线更改并将之前的路线存储为historyUrl(也可以将其存储在数组中)。 这里来自角度路由器的位置服务可以访问浏览器和历史记录。
以下是基础课程,您可以扩展至更高级的课程。
import { Injectable } from '@angular/core';
import { Location, NavigationEnd, Router } from '@angular/router';
@Injectable({
providedIn: 'root'
})
export class BackButtonService {
private historyUrl: string | null = null;
constructor(private location: Location, private router: Router) {
this.router.events.subscribe((event) => {
if (event instanceof NavigationEnd) {
this.historyUrl = event.urlAfterRedirects;
}
});
}
goBack() {
if (this.historyUrl) {
this.location.back();
} else {
// Handle the case where there's no history (e.g., initial route)
// You can stay on the current page or redirect to a specific route.
}
}
}