我认为首先要提一下queryParamMap 是从queryParams 派生的,这是一个BehaviorSubject,这一点很重要:
function createActivatedRoute(c: ActivatedRouteSnapshot) {
return new ActivatedRoute(
new BehaviorSubject(c.url), new BehaviorSubject(c.params), new BehaviorSubject(c.queryParams),
new BehaviorSubject(c.fragment), new BehaviorSubject(c.data), c.outlet, c.component, c);
}
Source
下面是queryParamMap 的获取方式:
get queryParamMap(): ParamMap {
if (!this._queryParamMap) {
this._queryParamMap = convertToParamMap(this.queryParams);
}
return this._queryParamMap;
}
Source
在后台创建了一个stream of transitions。因此,当您点击一个按钮时,一个新的过渡会被推送到该流中,这意味着必须激活新的路线:
export const activateRoutes =
(rootContexts: ChildrenOutletContexts, routeReuseStrategy: RouteReuseStrategy,
forwardEvent: (evt: Event) => void): MonoTypeOperatorFunction<NavigationTransition> =>
map(t => {
new ActivateRoutes(
routeReuseStrategy, t.targetRouterState!, t.currentRouterState, forwardEvent)
.activate(rootContexts);
return t;
});
Source
这将导致advanceActivatedRoute 被调用并最终到达this line:
(<any>route.queryParams).next(nextSnapshot.queryParams);
所以这应该是记录到控制台的第一条消息。
下一个是由于NavigationEnd event:
(this.events as Subject<Event>)
.next(new NavigationEnd(
t.id, this.serializeUrl(t.extractedUrl), this.serializeUrl(this.currentUrlTree)));
如果你想可视化这个,你可以打开这个StackBlitz,打开开发工具并放置一些断点:
- router_link.ts: 265 - 当你点击按钮时
- activated_routes.ts: 25 - 激活路由时
- router.ts: 1062 -
NavigationEnd 事件
- router_state.ts: 390 -
advanceActivatedRoute 的主体(在路由激活过程中)
- app.component.ts