angular11源码探索二十五[Router路由事件]
RouterEvent
触发事件的条件: routerLink
,navigateByUrl()
, navigate()
路由器整个经历的事件经历,而不是与特定路由相关的事件。对任何给定的导航触发一次。
上官网给的小案例
class MyService {
constructor(public router: Router, logger: Logger) {
router.events.pipe(
filter((e: Event): e is RouterEvent => e instanceof RouterEvent)
).subscribe((e: RouterEvent) => {
logger.log(e.id, e.url);
});
}
}
我们发现默认刷新页面有路由事件,刷新的是NavigationEnd
NavigationStart
当导航开始时触发的事件。
navigationTrigger
识别触发导航的呼叫或事件。
* 'imperative'触发器是对' router.navigateByUrl() '或' router.navigate() '的调用。
* popstate 的触发器 Location.方法 跳转
* hashchange 暂时没发现使用方法
navigationTrigger?: 'imperative'|'popstate'|'hashchange';
restoredState
pushState
当popstate
事件触发导航时,先前提供给呼叫的导航状态。否则为null。
写个案例你就懂了
<a [routerLink]="['a']" [state]="{foo: 'bar'}">aaa</a><br>
<a [routerLink]="['b']">bbb</a><br>
<a [routerLink]="['c']">ccc</a><br>
<a [routerLink]="['d']">ddd</a><br>
<bution (click)="clickMethod()">返回</button>
export class TwoComponent implements OnInit {
constructor(
private router:Router,
private location:Location
) {
this.router.events.pipe(
filter((e:Event)=>(e instanceof NavigationStart))
).subscribe(res=>{
console.log(res);
// {id: 2, url: "/home/b", navigationTrigger: "imperative", restoredState: null}
})
}
clickMethod() {
this.location.back()
}
}
当我们点击返回的时候,相当于通过restoredState
拿到之前的路由状态,类似滚动位置,state,hash,问好传参等, 参数参考NavigationExtras
RoutesRecognized
当路由被识别时触发的事件
NavigationError
由于意外错误导致导航失败时触发的事件。
当前路由 `/d`, 访问一个不存在的路由,报错信息,返回是当前的路由
export class TwoComponent implements OnInit {
constructor(
private router: Router,
private location: Location
) {
this.router.events.subscribe(e=>{
if (e instanceof NavigationError) {
console.log(e.url);
// 跳转报错的Url /home/dcccc
console.log(router.url);
// /d
console.log(location.path());
// /d
}
}
}
如果你想去掉控制台的报错信息,然后也不影响 NavigationError事件的正常的查询
this.router.navigate(['/home/dcccc']).catch(()=>null)
NavigationCancel
当导航被直接或间接取消时触发的事件。
路由守卫返回false
export class TwoService implements CanActivate{
// 如果您有在导航过程中返回的路线保护false,您将获得一个NavigationCancel事件。返回值是false,Promise解析为false还是Observable发出都没有关系false。最终结果将是相同的。
canActivate() {
// Case 1
return false;
// Case 2
return Promise.resolve(false);
// Case 3
return new Observable<boolean>(observer => {
observer.next(false);
observer.complete();
});
}
}
const routes: Routes = [{ path: '', component: TwoComponent,children:[
{path:'a',component:AComponent},
{path:'b',component:BComponent,
canActivate:[TwoService]
},
{path:'c',component:CComponent},
] }];
export class TwoComponent implements OnInit {
constructor(
private router: Router,
private location: Location
) {
this.router.events.subscribe(e=>{
if (e instanceof NavigationCancel) {
console.log(e);// 当前要跳转的事件信息
console.log(location.path());
//当前没跳转到的事件,加入当前是 /c 保存不变,路由守卫被拦截啦
}
})
}
}
当重定向也会触发
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean {
//手动启动一个新的导航和
//通过返回false取消当前的
this.router.navigateByUrl('/home/d')
return false
//第二种方法
//路由器将自动取消
//当前的导航并开始一个新的
this.router.parseUrl('/home/d')
}
// NavigationCancel {id: 5, url: "/home/b", reason: "Navigation ID 5 is not equal to the current navigation id 6"}
导航路线
NavigationStart
当导航开始时触发此事件
触发条件: popState(浏览器的前进/后退),navigateByUrl(),navigate()
如果是popState触发,那么我们获取前一个的状态
//如果跳转的是懒加载的路由路径
RouteConfigLoadStart
当延迟加载路由之前
RouteConfigLoadEnd
当延迟加载路由之后
RoutesRecognized
当路由被识别时触发的事件。
GuardsCheckStart
路由守卫阶段开始
ChildActivationStart
路由解析阶段的子孩子激活部分开始
ActivationStart
路由激活部分开始时触发
GuardsCheckEnd
路由守卫阶段结束时
ResolveStart
解决延迟守卫阶段开始
ResolveEnd
解决延迟守卫结束
ActivationEnd
路由激活部分结束时触发
ChildActivationEnd
路由解析阶段的子孩子激活结束时
Scroll
由滚动触发的事件
NavigationEnd
导航成功结束时触发的事件
NavigationCancel
当导航被直接或间接取消时触发的事件。
NavigationError
由于意外错误导致导航失败时触发的事件。
在懒加载中出来加载过长
可以通过懒加载的路由事件去修改
this.router.events.subscribe(event => {
if (event instanceof RouteConfigLoadStart) {
this.isRouteLoading = true;
} else if (event instanceof RouteConfigLoadEnd) {
this.isRouteLoading = false;
}
});
决定自己的高度的是你的态度,而不是你的才能
记得我们是终身初学者和学习者
总有一天我也能成为大佬