假设有以下路由配置:
const appRoutes: Routes = [
{
path: "home",
canMatch: [platformGuard],
canActivate: [authenticationGuard],
resolve: {userConfig: userConfigResolver},
loadChildren: () => import("@netway/home/home.module").then(value => value.HomeModule),
},
{
path: "pwa",
canMatch: [platformGuard],
canActivate: [authenticationGuard],
resolve: {userConfig: userConfigResolver},
loadChildren: () => import("@netway/pwa/pwa.module").then(value => value.PwaModule),
},
];
export const PwaRoutes: Routes = [
{
path: "",
pathMatch: "full",
redirectTo: "tab/home"
},
{
path: "tab",
canActivate: [authenticationGuard],
loadComponent: () => import("@netway/pwa/pwa.component").then((x) => x.PwaComponent),
children: [
{
path: "home",
loadComponent: () => import("@netway/pwa/tab/home/pwa-home.component").then((x) => x.PwaHomeComponent),
canActivateChild: [authenticationChildGuard],
children: [
{
path: "",
pathMatch: "full",
title: "pwa.tab.home",
loadComponent: () => import("@netway/pwa/tab/home/home-main/pwa-home-main.component").then((x) => x.PwaHomeMainComponent)
},
{
path: "page",
loadComponent: () => import("@netway/pwa/tab/home/home-children/pwa-home-children.component").then((x) => x.PwaHomeChildrenComponent),
children: [
{
path: "userCustomHome",
title: "menu.dashboard",
component: UserCustomHomeComponent,
data: {layoutName: LayoutName.HOME}
},
{
path: "process",
loadChildren: () => import("../process/process.module").then(p => p.ProcessModule)
},
{
path: "widgetProcess",
loadChildren: () => import("../widget-process/widget-process.module").then(p => p.WidgetProcessModule)
},
{
path: "depositList",
title: "depositList.title",
loadChildren: () => import("../deposit-list/deposit-list.module").then(d => d.DepositListModule)
},
{
path: "billStatements",
title: "depositList.actionBar.billAccount",
component: DepositBillStatementComponent
},
{
path: "loan",
title: "loan.menu.title",
loadChildren: () => import("../loan/loan.module").then(l => l.LoanModule)
},
{
path: "cardlessCash",
title: "cardless.page.title",
loadChildren: () => import("../cardless-cash/cardless-cash.module").then(c => c.CardlessCashModule)
},
]
}
]
},
]
}
];
"home/page/"
中的孩子雇佣体系与"pwa/tab/home/page/"
中的完全相同。
在我的代码中,我以某种方式导航到路径:this.router.navigate("home/page/[path to the desired child])
。正如您所看到的,没有 PWA 路径的迹象,因为它最近已添加到源代码中。
platformGuard 的作用是当设备是受支持的小工具时,将所有路径从
home
重定向到 pwa
。
现在,我的问题是如何在不修改源代码中数十个
this.router.navigate()
绝对路由调用的情况下路由到 PWA 路由?
目前,我推出了一项新服务,每当我必须以绝对方式路由时就使用它:
@Injectable({
providedIn: 'root'
})
export class PathService {
private readonly platformService = inject(PlatformService);
/**
* @desc Use this method when you have to navigate from one module to another one.
*
* IMPORTANT: Don't use this method when you can solve your issue using relative routes.
* @param partialPath The raw absolute path which needs to be modified based on the current mode (NW or PWA).
* @return The modified absolute path based on the current mode as an array of strings
*/
getAbsolute(...partialPath: ReadonlyArray<string>): Array<any> {
partialPath = this.format(...partialPath);
const pathPrefix = this.platformService.isPwaMode() ? ["pwa", "tab"] : [];
return [...pathPrefix, ...partialPath];
}
/**
* @desc Removes all the route slashes and flattens the path segments to a single array
*/
private format(...partialPath: Array<string>) {
return partialPath.flatMap(
pathSegment => pathSegment.split("/").filter(segment => segment !== "")
);
}
}
一个示例用法:
this.router.navigate(
this.pathService.getAbsolute("home", "page", "kartablRegister"),
{
queryParams: { kartablId: kartablId, asEditing: true }
}
);
此解决方案的缺点是我需要修改所有
this.router.navigate()
调用。
如何在无需修改现有
this.router.navigate()
调用的情况下获得相同的结果?
我想实现此目的的一种方法是在非 PWA 路由上添加
canActivateChild
,如果应用程序在支持的平台上运行,它将重定向到匹配的 PWA 路由:
const appRoutes: Routes = [
{
path: "home",
canMatch: [platformGuard],
canActivate: [authenticationGuard],
// Here is the new CanActivate
canActivateChild: [platformRedirectGuard],
resolve: {userConfig: userConfigResolver},
loadChildren: () => import("@netway/home/home.module").then(value => value.HomeModule),
},
{
path: "pwa",
canMatch: [platformGuard],
canActivate: [authenticationGuard],
resolve: {userConfig: userConfigResolver},
loadChildren: () => import("@netway/pwa/pwa.module").then(value => value.PwaModule),
},
];
现在将在“home”的每个子路由上运行的守卫可以检测设备是否与您的
platformGuard
所做的兼容,在兼容设备上,它将重写路径以将用户重定向到 PWA 上的适当路由您的应用程序的版本。
export const platformRedirectGuard: CanActivateFn = (route, state) => {
// Use your service to detect compatible devices :
const platformService = inject(PlatformService);
if (platformService.compatiblePlatform()) {
// Redirect to the matching pwa route
return inject(Router).createUrlTree(['/pwa/tab' + state.url]);
}
return true;
};
但这也意味着
platformRedirect
函数将在指向根“home”路径的 router.navigate
上运行。