NavigationStart导航开始。每当路由器检测到对路由器链接指令的点击时,它就会开始导航周期。还有启动导航的命令式方法,例如路由器服务navigate和navigateByUrl方法
RoutesRecognized 当路由器解析 URL 并识别路由时。路由器首先对路由器配置数组(ROUTES在我们的示例中)进行深度优先搜索,并尝试将 URL/users与路由器配置中的属性之一进行匹配path,同时沿途应用任何重定向。如果匹配的路径需要延迟加载模块,则此时将加载该模块。路由器发出一个RoutesRecognized事件来表明它已找到 URL 的匹配项以及要导航到的组件 (UsersComponent)。
GuardsCheckStart 路由器开始路由守卫阶段时
所有的active deactive load之类的 Guards此时执行(具体每种的执行时间有区别,此时先执行的是deactive。active会等到GuardsCheckEnd之前执行。)
注意,相同的url导航时会忽略,除非RouterModule.forRoot中配置onSameUrlNavigation: 'reload'。并且Route中配置runGuardsAndResolvers: 'always'。
deactive返回true,则守卫成功通过。否则,守卫会失败。此时会忽略两个activationStart事件,直接发出GuardsCheckEnd事件。随后发出一个NavigationCancel事件,并中止整个导航。
ChildActivationStart 路由器开始激活路由的子节点时, 未匹配任何路由,将不会触发。
ActivationStart、ActivationEnd、ChildActivationStart、ChildActivationEnd这四个事件是配套的。表示激活组件,渲染组件(节点在ResolveEnd之后,ChildActivationEnd之前),并使用 a 标签显示active。
ActivationStart路由器开始激活路由时, 未匹配任何路由,将不会触发。
GuardsCheckEnd 当路由器成功完成路由守卫
如果上一步的active返回false(或者前面的deactive返回false),那么会在GuardsCheckEnd结束后发出一个NavigationCancel,然后终止后面的所有事件。
ResolveStart 当路由器开始路由的解析 阶段时, 未匹配任何路由,将不会触发。
所有的Resolve 此时执行,详见angular 路由的Resolve教程。
ResolveEnd 当路由器成功完成路由的解析 阶段时
1 前一个组件的Ondestroy 方法执行
2 router-outlet上前一个组件的deactive事件触发:(deactivate)="deactivate($event)"。此处的$event是前一个组件的实例。
3 constructor 组建实例此时创建。如果在constructor中监听router.evens,那么在此只有此后的3个End事件会被监听到(当然也会监听到下一次导航的前8个事件)
4 router-outlet上的active事件触发,(activate)="activate($event)"此处的$event是当前实例化组件的实例。
5 RouterOutlet.activateEvents 触发, 此处也可以通过订阅获取组件实例。this.outlet.activateEvents.subscribe(c => console.log(c))
6 navigateByUrl("/l1/l2/l3/view3", {state: {a:"historystate"}}) 中的state数据会被压入浏览器的history.state属性中,因此后三个事件和之后的所有时间点都可以获取到state数据。
ActivationEnd 当路由器完成激活路由时
ChildActivationEnd 当路由器完成激活路由的子节点时
NavigationEnd 导航成功结束时
1 router.navigate.then navigate返回的promise在此时触发then,并且传入一个参数true。
2 如果导航中间被active之类的guard阻止,那么router.navigate的then会在NavigationCancel 发出之后执行,并且传入一个false作为参数。
3 如果是相同的url被忽略的话,then会立即执行,传入的参数会是null。
router.getCurrentNavigation() 导航结束后将不再返回对象,而是null。
ngOnInit 进入组建的生命周期
ngAfterViewInit
导航开始前添加的其他异步任务 setTimeout/promise
通过outlet获取组建实例
import { Directive } from '@angular/core';
import { Router, RouterOutlet } from '@angular/router';
@Directive({
selector: 'router-outlet'
})
export class ActivatedComponentsDirective {
constructor(r: RouterOutlet, public router: Router) {
r.activateEvents.subscribe(compInstance => {
console.log(router.getCurrentNavigation())
console.log(compInstance)
})
}
}
路由守卫
class AGuard implements CanActivate, Resolve<string> {
resolve(route: ActivatedRouteSnapshot,state: RouterStateSnapshot) {
console.log("Resolve")
return "resolve"
}
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) : boolean | UrlTree | Observable<boolean | UrlTree> {
console.log("AGuard")
return true
}
}
const routes: Routes = [
{
path: 'a',
component: AComponent,
canActivate: [AGuard],
resolve: {
"astring": AGuard
}
},
{
path: 'b',
component: BComponent,
children: [
{
path: 'c',
component: CComponent,
}
]
}
];