有关我的应用程序的信息(Angular 12):
- 由 3 个模块组成,每个模块都有一个带有列表的概述页面和一些详细信息页面
- 每条路线都有一个区域标签,因此我知道用户正在哪个模块中导航
所以我想实现 Angular 的 RouteReuseStrategy 来实现以下行为:
-
每当用户从列表 -> 详细信息页面导航并使用后退按钮时,应重用列表组件(检测后退按钮触发器)
-
每当用户从不同的模块/区域导航到列表组件时,不应重用列表组件
-
每当用户从详细信息导航到另一个详细信息页面时,应该重用详细信息组件(默认行为?)
-
每当用户通过导航到另一个模块或注销而离开模块时,应清除/销毁存储的组件
现在的情况:
-
我实现了一个自定义 RouteReuseStrategy,它可以工作并且列表组件被重用 ✓
-
我想检查路线内的航空标签,但 ActivatedRouteSnapshot 是空的 ✕
-
检测后退按钮按下,但事件经常触发,如果我实现基本后退标志,它就会中断✕
缺什么?
-
检测后退按钮导航并修改组件的复用
-
检测路由属于哪个模块,以修改重用或清理存储的组件
Code:
路线示例在模块 A 中
{
path: 'lista',
component: ListAComponent,
data: {
title: 'List overview',
areaCategory: AreaCategory.A,
reuseRoute: true,
},
},
{
path: 'lista/:id',
component: DetailAComponent,
data: {
title: 'Detail',
areaCategory: AreaCategory.A,
reuseRoute: false,
},
},
路线示例模块B
{
path: 'listb',
component: ListBComponent,
data: {
title: 'List overview',
areaCategory: AreaCategory.B,
reuseRoute: true,
},
},
{
path: 'listb/:id',
component: DetailBComponent,
data: {
title: 'Detail',
areaCategory: AreaCategory.B,
reuseRoute: false,
},
},
应用程序模块.ts
providers: [
{
provide: RouteReuseStrategy,
useClass: CustomReuseRouteStrategy,
}
],
在全球范围内应该没问题,还是我需要将其移动到 3 个模块中的每一个?
重用路由策略
@Injectable()
export class CustomReuseRouteStrategy implements RouteReuseStrategy {
private handlers: { [key: string]: DetachedRouteHandle } = {};
// Detect Backbutton-navigation
back = false;
constructor(location: LocationStrategy) {
location.onPopState(() => {
this.back = true;
});
}
shouldDetach(route: ActivatedRouteSnapshot): boolean {
if (!route.routeConfig || route.routeConfig.loadChildren) {
return false;
}
// Check route.data.reuse whether this route should be re used or not
let shouldReuse = false;
if (
route.routeConfig.data &&
route.routeConfig.data.reuseRoute &&
typeof route.routeConfig.data.reuseRoute === 'boolean'
) {
shouldReuse = route.routeConfig.data.reuseRoute;
}
return shouldReuse;
}
store(route: ActivatedRouteSnapshot, handler: DetachedRouteHandle): void {
if (handler) {
this.handlers[this.getUrl(route)] = handler;
}
}
shouldAttach(route: ActivatedRouteSnapshot): boolean {
if (!this.back) {
return false;
}
return !!this.handlers[this.getUrl(route)];
}
retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle {
if (!this.back || !route.routeConfig || route.routeConfig.loadChildren) {
return null;
}
//this.back = false; -> does not work fires to often
return this.handlers[this.getUrl(route)];
}
shouldReuseRoute(future: ActivatedRouteSnapshot, current: ActivatedRouteSnapshot): boolean {
/** We only want to reuse the route if the data of the route config contains a reuse true boolean */
let reUseUrl = false;
if (future.routeConfig && future.routeConfig.data && typeof future.routeConfig.data.reuseRoute === 'boolean') {
reUseUrl = future.routeConfig.data.reuseRoute;
}
//const defaultReuse = future.routeConfig === current.routeConfig; -> used for navigating to same component but routeConfigs are empty therefore always match?
return reUseUrl;
}
private getUrl(route: ActivatedRouteSnapshot): string {
if (route.routeConfig) {
const url = route.routeConfig.path;
return url;
}
}
clearHandles() {
for (const key in this.handlers) {
if (this.handlers[key]) {
this.destroyHandle(this.handlers[key]);
}
}
this.handlers = {};
}
private destroyHandle(handle: DetachedRouteHandle): void {
const componentRef: ComponentRef<any> = handle['componentRef'];
if (componentRef) {
componentRef.destroy();
}
}
}
我注意到_routerStateActivatedRouteSnapshot 内部保存着 url,可用于区分模块,但我宁愿从路由数据中检查areaCategory,但奇怪的是,shouldReuseRoute 方法中的未来和当前的ActivatedRouteSnapshots 大部分都是空的
另外,我不确定是否使用 _routerState 这样的内部值,因为我听说这些值不是固定的,可以随时更改
空的未来和当前快照的日志(只有网址有用)
为什么应用组件代替Detail or 列表组件?
也许这就是数据为空的原因?
我需要获取正确的路线/组件来访问区域类别以实现所需的行为。
按照这里的要求,这是一个简单的堆栈闪电战 https://stackblitz.com/edit/angular-ivy-onz5ma?file=src/app/module-c/routing-c.module.ts用我的设置
如果我错过了什么,请告诉我,非常感谢您的帮助