这个其实很简单,在angular也给出了相应的解决方案即
1.如果跳转发生在html中即使用routerLink时加上replaceUrl="true"即可
<button routerLink="/order" replaceUrl="true">to order</button>
2.如果跳转发生在ts中即
this.router.navigate(['/order'], { replaceUrl: true });
参数中添加replaceUrl字段使其为true即可
这样就实现了某个路由跳转不记录在浏览器历史中
需求升级为所有路由跳转都不记录在浏览器历史中
产生需求原因:
在ios10以上系统中的微信中访问页面时(所有前端页面,也包括angular)涉及到连接跳转就会出现底部导航区(前进和返回按钮),这大大影响了页面的美观。为了在ios不出现此底部导航区,目前微信并没有给出像样的解决烦恼,这就要用程序欺骗的方式隐蔽掉这个问题,即让所有跳转都不记录到历史中,这样就对系统隐瞒了程序中的所有跳转,自然就不会出现这个烦人的导航区了。
angular解决方案
有了上述replaceUrl:true的知识自然就想到在所有跳转的页面都加上 replaceUrl
这当然可行,但是如果跳转过多,工作量和维护成本将很大,加上后期判断是否是ios,是安卓则不需要加,这无疑是一场灾难。
这就不得不想到要用一个全局的配置去解决这个问题,但是操蛋的是在angular文档中并没有发现全局配置方案。
然鹅,只能使用曲线救国方案来使这一切看起来更加优雅。
先放方案再做解释
angular 路由守卫+逻辑代码
app-routing.module.ts
hash-type-guard.service.ts
我们知道路由守卫可以对路由跳转进行拦截
这就给我们提供了良好的解决入口,写个路由守卫拦截所有的跳转路由,在使用我们自己的逻辑进行跳转
这样就实现了每一次跳转都不会记录到浏览器历史中。
为何不使用 canActivateChild?
如果我没有懒加载模块,使用canActivateChild会更加简洁
但是canActivateChild的子模块中有使用懒加载模块就会执行两次路由守卫的canActivateChild方法
这个不知道是不是angular 中的bug还是有意为之,但是这无疑是混乱的,所以我放弃了canActivateChild
针对懒加载模块 canActivateChild 会执行两次路由守卫的 canActivateChild方法 的解释
这个canActivateChild方法中有2个参数,根据第一个参数对象中的url数组可以得到跳转目标路由
执行第一次时这个url数组是有一个值得
执行第二次的时候这个url数组是空值
所以根据这个url的长度判断可以忽略第二次的进入
这样就可以做到使用 canActivateChild 去监听懒加载模块路由也不会存在问题了
以下给出例子app-routing.module.ts
import { NgModule } from '@angular/core'; import { Router, Routes, RouterModule, PreloadAllModules, NavigationStart } from '@angular/router'; import { HomeComponent } from './layout/home/home.component'; import { DashboardComponent } from './routes/dashboard/dashboard.component'; import { ProductComponent, ChildComponent } from './routes/product/product.component'; // CanDeactivate import { UnsaveGuard } from './guard/unsave-guard.service'; import { ProductResolve } from './guard/product-resolve.service'; // CanActivate import { HashTypeGuard } from './guard/hash-type-guard.service'; const routes: Routes = [ { path: '', component: HomeComponent, // canActivate: [HashTypeGuard], canActivateChild: [ HashTypeGuard ], children: [ { path: '', redirectTo: 'dashboard', pathMatch: 'full' }, { path: 'task', loadChildren: () => import('./routes/task/task.module').then(m => m.TaskModule), // canActivate: [HashTypeGuard], }, { path: 'inherit', loadChildren: () => import('./routes/inherit/inherit.module').then(m => m.InheritModule), // canActivate: [HashTypeGuard], }, { path: 'cesiums', loadChildren: () => import('./routes/cesiums/cesium.module').then(m => m.CesiumModule) // ,canActivate: [HashTypeGuard], }, { path: 'webrtc', loadChildren: () => import('./routes/webrtc/webrtc.module').then(m => m.WebrtcModule) // ,canActivate: [HashTypeGuard], }, { path: 'dashboard', component: DashboardComponent, // canActivate: [HashTypeGuard], }, { path: 'a', pathMatch: 'prefix', children: [ // { path:'**', pathMatch: 'prefix',redirectTo: 'dashboard'} { path:'**', component: ChildComponent}, ] }, { path: 'product/:id', component: ProductComponent, resolve: { product: ProductResolve } }, { path: 'order', loadChildren: () => import('./routes/order/order.module').then(m => m.OrderModule), canDeactivate: [UnsaveGuard] , // canActivate: [HashTypeGuard], data: {val: '005'} }, { path: '**', redirectTo: 'home' } ] } ]; @NgModule({ imports: [RouterModule.forRoot(routes, { useHash: true, preloadingStrategy: PreloadAllModules, // enableTracing: true, // onSameUrlNavigation: 'reload' })], // providers: [UnsaveGuard], exports: [RouterModule] }) export class AppRoutingModule { }hash-type-guard.service.ts
import { Injectable } from '@angular/core'; import { Router, CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, CanActivateChild, CanLoad } from '@angular/router'; @Injectable({providedIn: 'root'}) export class HashTypeGuard implements CanActivate, CanActivateChild, CanLoad { canLoad(route: import("@angular/router").Route, segments: import("@angular/router").UrlSegment[]): boolean { this.val++; console.log('canload'+this.val); return true; } val = 0; constructor( private router: Router ) {} canActivateChild(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) { if(route.url.length) { this.val++; if(this.val%2){ this.router.navigate([state.url], { replaceUrl: true }); return false; }else{ console.log(this.val); return true; } } return true; } }
2021-08-05 04:46
大白话听起来就是舒服。比起装逼的博客文绉绉的谢了一堆,最后毛线都没讲明白。