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

当导航开始时触发的事件。

navigationTrigger

识别触发导航的呼叫或事件。

* 'imperative'触发器是对' router.navigateByUrl() '或' router.navigate() '的调用。
* popstate 的触发器  Location.方法 跳转
* hashchange 暂时没发现使用方法
navigationTrigger?: 'imperative'|'popstate'|'hashchange';

restoredState

pushStatepopstate事件触发导航时,先前提供给呼叫的导航状态。否则为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

​ 当路由被识别时触发的事件

​ 由于意外错误导致导航失败时触发的事件。

当前路由 `/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)                            

当导航被直接或间接取消时触发的事件。

路由守卫返回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;
    }
});
posted @ 2021-01-21 09:44  猫神甜辣酱  阅读(641)  评论(0编辑  收藏  举报