angular-cn/packages/router/src/events.ts

482 lines
13 KiB
TypeScript

/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import {Route} from './config';
import {ActivatedRouteSnapshot, RouterStateSnapshot} from './router_state';
/**
* Identifies the call or event that triggered a navigation.
*
* * 'imperative': Triggered by `router.navigateByUrl()` or `router.navigate()`.
* * 'popstate' : Triggered by a `popstate` event.
* * 'hashchange'-: Triggered by a `hashchange` event.
*
* @publicApi
*/
export type NavigationTrigger = 'imperative'|'popstate'|'hashchange';
/**
* Base for events the router goes through, as opposed to events tied to a specific
* route. Fired one time for any given navigation.
*
* The following code shows how a class subscribes to router events.
*
* ```ts
* 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);
* });
* }
* }
* ```
*
* @see `Event`
* @see [Router events summary](guide/router#router-events)
* @publicApi
*/
export class RouterEvent {
constructor(
/** A unique ID that the router assigns to every router navigation. */
public id: number,
/** The URL that is the destination for this navigation. */
public url: string) {}
}
/**
* An event triggered when a navigation starts.
*
* @publicApi
*/
export class NavigationStart extends RouterEvent {
/**
* Identifies the call or event that triggered the navigation.
* An `imperative` trigger is a call to `router.navigateByUrl()` or `router.navigate()`.
*
* @see `NavigationEnd`
* @see `NavigationCancel`
* @see `NavigationError`
*/
navigationTrigger?: 'imperative'|'popstate'|'hashchange';
/**
* The navigation state that was previously supplied to the `pushState` call,
* when the navigation is triggered by a `popstate` event. Otherwise null.
*
* The state object is defined by `NavigationExtras`, and contains any
* developer-defined state value, as well as a unique ID that
* the router assigns to every router transition/navigation.
*
* From the perspective of the router, the router never "goes back".
* When the user clicks on the back button in the browser,
* a new navigation ID is created.
*
* Use the ID in this previous-state object to differentiate between a newly created
* state and one returned to by a `popstate` event, so that you can restore some
* remembered state, such as scroll position.
*
*/
restoredState?: {[k: string]: any, navigationId: number}|null;
constructor(
/** @docsNotRequired */
id: number,
/** @docsNotRequired */
url: string,
/** @docsNotRequired */
navigationTrigger: 'imperative'|'popstate'|'hashchange' = 'imperative',
/** @docsNotRequired */
restoredState: {[k: string]: any, navigationId: number}|null = null) {
super(id, url);
this.navigationTrigger = navigationTrigger;
this.restoredState = restoredState;
}
/** @docsNotRequired */
toString(): string {
return `NavigationStart(id: ${this.id}, url: '${this.url}')`;
}
}
/**
* An event triggered when a navigation ends successfully.
*
* @see `NavigationStart`
* @see `NavigationCancel`
* @see `NavigationError`
*
* @publicApi
*/
export class NavigationEnd extends RouterEvent {
constructor(
/** @docsNotRequired */
id: number,
/** @docsNotRequired */
url: string,
/** @docsNotRequired */
public urlAfterRedirects: string) {
super(id, url);
}
/** @docsNotRequired */
toString(): string {
return `NavigationEnd(id: ${this.id}, url: '${this.url}', urlAfterRedirects: '${
this.urlAfterRedirects}')`;
}
}
/**
* An event triggered when a navigation is canceled, directly or indirectly.
* This can happen when a route guard
* returns `false` or initiates a redirect by returning a `UrlTree`.
*
* @see `NavigationStart`
* @see `NavigationEnd`
* @see `NavigationError`
*
* @publicApi
*/
export class NavigationCancel extends RouterEvent {
constructor(
/** @docsNotRequired */
id: number,
/** @docsNotRequired */
url: string,
/** @docsNotRequired */
public reason: string) {
super(id, url);
}
/** @docsNotRequired */
toString(): string {
return `NavigationCancel(id: ${this.id}, url: '${this.url}')`;
}
}
/**
* An event triggered when a navigation fails due to an unexpected error.
*
* @see `NavigationStart`
* @see `NavigationEnd`
* @see `NavigationCancel`
*
* @publicApi
*/
export class NavigationError extends RouterEvent {
constructor(
/** @docsNotRequired */
id: number,
/** @docsNotRequired */
url: string,
/** @docsNotRequired */
public error: any) {
super(id, url);
}
/** @docsNotRequired */
toString(): string {
return `NavigationError(id: ${this.id}, url: '${this.url}', error: ${this.error})`;
}
}
/**
* An event triggered when routes are recognized.
*
* @publicApi
*/
export class RoutesRecognized extends RouterEvent {
constructor(
/** @docsNotRequired */
id: number,
/** @docsNotRequired */
url: string,
/** @docsNotRequired */
public urlAfterRedirects: string,
/** @docsNotRequired */
public state: RouterStateSnapshot) {
super(id, url);
}
/** @docsNotRequired */
toString(): string {
return `RoutesRecognized(id: ${this.id}, url: '${this.url}', urlAfterRedirects: '${
this.urlAfterRedirects}', state: ${this.state})`;
}
}
/**
* An event triggered at the start of the Guard phase of routing.
*
* @see `GuardsCheckEnd`
*
* @publicApi
*/
export class GuardsCheckStart extends RouterEvent {
constructor(
/** @docsNotRequired */
id: number,
/** @docsNotRequired */
url: string,
/** @docsNotRequired */
public urlAfterRedirects: string,
/** @docsNotRequired */
public state: RouterStateSnapshot) {
super(id, url);
}
toString(): string {
return `GuardsCheckStart(id: ${this.id}, url: '${this.url}', urlAfterRedirects: '${
this.urlAfterRedirects}', state: ${this.state})`;
}
}
/**
* An event triggered at the end of the Guard phase of routing.
*
* @see `GuardsCheckStart`
*
* @publicApi
*/
export class GuardsCheckEnd extends RouterEvent {
constructor(
/** @docsNotRequired */
id: number,
/** @docsNotRequired */
url: string,
/** @docsNotRequired */
public urlAfterRedirects: string,
/** @docsNotRequired */
public state: RouterStateSnapshot,
/** @docsNotRequired */
public shouldActivate: boolean) {
super(id, url);
}
toString(): string {
return `GuardsCheckEnd(id: ${this.id}, url: '${this.url}', urlAfterRedirects: '${
this.urlAfterRedirects}', state: ${this.state}, shouldActivate: ${this.shouldActivate})`;
}
}
/**
* An event triggered at the the start of the Resolve phase of routing.
*
* Runs in the "resolve" phase whether or not there is anything to resolve.
* In future, may change to only run when there are things to be resolved.
*
* @see `ResolveEnd`
*
* @publicApi
*/
export class ResolveStart extends RouterEvent {
constructor(
/** @docsNotRequired */
id: number,
/** @docsNotRequired */
url: string,
/** @docsNotRequired */
public urlAfterRedirects: string,
/** @docsNotRequired */
public state: RouterStateSnapshot) {
super(id, url);
}
toString(): string {
return `ResolveStart(id: ${this.id}, url: '${this.url}', urlAfterRedirects: '${
this.urlAfterRedirects}', state: ${this.state})`;
}
}
/**
* An event triggered at the end of the Resolve phase of routing.
* @see `ResolveStart`.
*
* @publicApi
*/
export class ResolveEnd extends RouterEvent {
constructor(
/** @docsNotRequired */
id: number,
/** @docsNotRequired */
url: string,
/** @docsNotRequired */
public urlAfterRedirects: string,
/** @docsNotRequired */
public state: RouterStateSnapshot) {
super(id, url);
}
toString(): string {
return `ResolveEnd(id: ${this.id}, url: '${this.url}', urlAfterRedirects: '${
this.urlAfterRedirects}', state: ${this.state})`;
}
}
/**
* An event triggered before lazy loading a route configuration.
*
* @see `RouteConfigLoadEnd`
*
* @publicApi
*/
export class RouteConfigLoadStart {
constructor(
/** @docsNotRequired */
public route: Route) {}
toString(): string {
return `RouteConfigLoadStart(path: ${this.route.path})`;
}
}
/**
* An event triggered when a route has been lazy loaded.
*
* @see `RouteConfigLoadStart`
*
* @publicApi
*/
export class RouteConfigLoadEnd {
constructor(
/** @docsNotRequired */
public route: Route) {}
toString(): string {
return `RouteConfigLoadEnd(path: ${this.route.path})`;
}
}
/**
* An event triggered at the start of the child-activation
* part of the Resolve phase of routing.
* @see `ChildActivationEnd`
* @see `ResolveStart`
*
* @publicApi
*/
export class ChildActivationStart {
constructor(
/** @docsNotRequired */
public snapshot: ActivatedRouteSnapshot) {}
toString(): string {
const path = this.snapshot.routeConfig && this.snapshot.routeConfig.path || '';
return `ChildActivationStart(path: '${path}')`;
}
}
/**
* An event triggered at the end of the child-activation part
* of the Resolve phase of routing.
* @see `ChildActivationStart`
* @see `ResolveStart`
* @publicApi
*/
export class ChildActivationEnd {
constructor(
/** @docsNotRequired */
public snapshot: ActivatedRouteSnapshot) {}
toString(): string {
const path = this.snapshot.routeConfig && this.snapshot.routeConfig.path || '';
return `ChildActivationEnd(path: '${path}')`;
}
}
/**
* An event triggered at the start of the activation part
* of the Resolve phase of routing.
* @see `ActivationEnd`
* @see `ResolveStart`
*
* @publicApi
*/
export class ActivationStart {
constructor(
/** @docsNotRequired */
public snapshot: ActivatedRouteSnapshot) {}
toString(): string {
const path = this.snapshot.routeConfig && this.snapshot.routeConfig.path || '';
return `ActivationStart(path: '${path}')`;
}
}
/**
* An event triggered at the end of the activation part
* of the Resolve phase of routing.
* @see `ActivationStart`
* @see `ResolveStart`
*
* @publicApi
*/
export class ActivationEnd {
constructor(
/** @docsNotRequired */
public snapshot: ActivatedRouteSnapshot) {}
toString(): string {
const path = this.snapshot.routeConfig && this.snapshot.routeConfig.path || '';
return `ActivationEnd(path: '${path}')`;
}
}
/**
* An event triggered by scrolling.
*
* @publicApi
*/
export class Scroll {
constructor(
/** @docsNotRequired */
readonly routerEvent: NavigationEnd,
/** @docsNotRequired */
readonly position: [number, number]|null,
/** @docsNotRequired */
readonly anchor: string|null) {}
toString(): string {
const pos = this.position ? `${this.position[0]}, ${this.position[1]}` : null;
return `Scroll(anchor: '${this.anchor}', position: '${pos}')`;
}
}
/**
* Router events that allow you to track the lifecycle of the router.
*
* The events occur in the following sequence:
*
* * [NavigationStart](api/router/NavigationStart): Navigation starts.
* * [RouteConfigLoadStart](api/router/RouteConfigLoadStart): Before
* the router [lazy loads](/guide/router#lazy-loading) a route configuration.
* * [RouteConfigLoadEnd](api/router/RouteConfigLoadEnd): After a route has been lazy loaded.
* * [RoutesRecognized](api/router/RoutesRecognized): When the router parses the URL
* and the routes are recognized.
* * [GuardsCheckStart](api/router/GuardsCheckStart): When the router begins the *guards*
* phase of routing.
* * [ChildActivationStart](api/router/ChildActivationStart): When the router
* begins activating a route's children.
* * [ActivationStart](api/router/ActivationStart): When the router begins activating a route.
* * [GuardsCheckEnd](api/router/GuardsCheckEnd): When the router finishes the *guards*
* phase of routing successfully.
* * [ResolveStart](api/router/ResolveStart): When the router begins the *resolve*
* phase of routing.
* * [ResolveEnd](api/router/ResolveEnd): When the router finishes the *resolve*
* phase of routing successfuly.
* * [ChildActivationEnd](api/router/ChildActivationEnd): When the router finishes
* activating a route's children.
* * [ActivationEnd](api/router/ActivationStart): When the router finishes activating a route.
* * [NavigationEnd](api/router/NavigationEnd): When navigation ends successfully.
* * [NavigationCancel](api/router/NavigationCancel): When navigation is canceled.
* * [NavigationError](api/router/NavigationError): When navigation fails
* due to an unexpected error.
* * [Scroll](api/router/Scroll): When the user scrolls.
*
* @publicApi
*/
export type Event = RouterEvent|RouteConfigLoadStart|RouteConfigLoadEnd|ChildActivationStart|
ChildActivationEnd|ActivationStart|ActivationEnd|Scroll;