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

458 lines
11 KiB
TypeScript
Raw Normal View History

/**
* @license
* Copyright Google Inc. 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';
/**
* @description
*
* Identifies the trigger of the 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';
/**
* @description
*
* Base for events the Router goes through, as opposed to events tied to a specific
* Route. `RouterEvent`s will only be fired one time for any given navigation.
*
* Example:
*
* ```
* class MyService {
* constructor(public router: Router, logger: Logger) {
* router.events.pipe(
* filter(e => e instanceof RouterEvent)
* ).subscribe(e => {
* logger.log(e.id, e.url);
* });
* }
* }
* ```
*
* @publicApi
*/
export class RouterEvent {
constructor(
/** @docsNotRequired */
public id: number,
/** @docsNotRequired */
public url: string) {}
}
/**
* @description
*
* Represents an event triggered when a navigation starts.
*
* @publicApi
*/
export class NavigationStart extends RouterEvent {
/**
* Identifies the trigger of the navigation.
*
* * 'imperative'--triggered by `router.navigateByUrl` or `router.navigate`.
* * 'popstate'--triggered by a popstate event
* * 'hashchange'--triggered by a hashchange event
*/
navigationTrigger?: 'imperative'|'popstate'|'hashchange';
/**
* This contains the navigation id that pushed the history record that the router navigates
* back to. This is not null only when the navigation is triggered by a popstate event.
*
* The router assigns a navigationId to every router transition/navigation. Even when the user
* clicks on the back button in the browser, a new navigation id will be created. So from
* the perspective of the router, the router never "goes back". By using the `restoredState`
* and its navigationId, you can implement behavior that differentiates between creating new
* states
* and popstate events. In the latter case you can restore some remembered state (e.g., scroll
* position).
*/
restoredState?: {navigationId: number}|null;
constructor(
/** @docsNotRequired */
id: number,
/** @docsNotRequired */
url: string,
/** @docsNotRequired */
navigationTrigger: 'imperative'|'popstate'|'hashchange' = 'imperative',
/** @docsNotRequired */
restoredState: {navigationId: number}|null = null) {
super(id, url);
this.navigationTrigger = navigationTrigger;
this.restoredState = restoredState;
}
/** @docsNotRequired */
toString(): string { return `NavigationStart(id: ${this.id}, url: '${this.url}')`; }
}
/**
* @description
*
* Represents an event triggered when a navigation ends successfully.
*
* @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}')`;
}
}
/**
* @description
*
* Represents an event triggered when a navigation is canceled.
*
* @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}')`; }
}
/**
* @description
*
* Represents an event triggered when a navigation fails due to an unexpected error.
*
* @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})`;
}
}
/**
* @description
*
* Represents 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})`;
}
}
/**
* @description
*
* Represents the start of the Guard phase of routing.
*
* @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})`;
}
}
/**
* @description
*
* Represents the end of the Guard phase of routing.
*
* @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})`;
}
}
/**
* @description
*
* Represents the start of the Resolve phase of routing. The timing of this
* event may change, thus it's experimental. In the current iteration it will run
* in the "resolve" phase whether there's things to resolve or not. In the future this
* behavior may change to only run when there are things to be resolved.
*
* @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})`;
}
}
/**
* @description
*
* Represents the end of the Resolve phase of routing. See note on
* `ResolveStart` for use of this experimental API.
*
* @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})`;
}
}
/**
* @description
*
* Represents an event triggered before lazy loading a route config.
*
* @publicApi
*/
export class RouteConfigLoadStart {
constructor(
/** @docsNotRequired */
public route: Route) {}
toString(): string { return `RouteConfigLoadStart(path: ${this.route.path})`; }
}
/**
* @description
*
* Represents an event triggered when a route has been lazy loaded.
*
* @publicApi
*/
export class RouteConfigLoadEnd {
constructor(
/** @docsNotRequired */
public route: Route) {}
toString(): string { return `RouteConfigLoadEnd(path: ${this.route.path})`; }
}
/**
* @description
*
* Represents the start of end of the Resolve phase of routing. See note on
* `ChildActivationEnd` for use of this experimental API.
*
* @publicApi
*/
export class ChildActivationStart {
constructor(
/** @docsNotRequired */
public snapshot: ActivatedRouteSnapshot) {}
toString(): string {
const path = this.snapshot.routeConfig && this.snapshot.routeConfig.path || '';
return `ChildActivationStart(path: '${path}')`;
}
}
/**
* @description
*
* Represents the start of end of the Resolve phase of routing. See note on
* `ChildActivationStart` for use of this experimental API.
*
* @publicApi
*/
export class ChildActivationEnd {
constructor(
/** @docsNotRequired */
public snapshot: ActivatedRouteSnapshot) {}
toString(): string {
const path = this.snapshot.routeConfig && this.snapshot.routeConfig.path || '';
return `ChildActivationEnd(path: '${path}')`;
}
}
/**
* @description
*
* Represents the start of end of the Resolve phase of routing. See note on
* `ActivationEnd` for use of this experimental API.
*
* @publicApi
*/
export class ActivationStart {
constructor(
/** @docsNotRequired */
public snapshot: ActivatedRouteSnapshot) {}
toString(): string {
const path = this.snapshot.routeConfig && this.snapshot.routeConfig.path || '';
return `ActivationStart(path: '${path}')`;
}
}
/**
* @description
*
* Represents the start of end of the Resolve phase of routing. See note on
* `ActivationStart` for use of this experimental API.
*
* @publicApi
*/
export class ActivationEnd {
constructor(
/** @docsNotRequired */
public snapshot: ActivatedRouteSnapshot) {}
toString(): string {
const path = this.snapshot.routeConfig && this.snapshot.routeConfig.path || '';
return `ActivationEnd(path: '${path}')`;
}
}
/**
* @description
*
* Represents a scrolling event.
*
* @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}')`;
}
}
/**
* @description
*
* Represents a router event, allowing you to track the lifecycle of the router.
*
* The sequence of router events is:
*
* - `NavigationStart`,
* - `RouteConfigLoadStart`,
* - `RouteConfigLoadEnd`,
* - `RoutesRecognized`,
* - `GuardsCheckStart`,
* - `ChildActivationStart`,
* - `ActivationStart`,
* - `GuardsCheckEnd`,
* - `ResolveStart`,
* - `ResolveEnd`,
* - `ActivationEnd`
* - `ChildActivationEnd`
* - `NavigationEnd`,
* - `NavigationCancel`,
* - `NavigationError`
* - `Scroll`
*
* @publicApi
*/
export type Event = RouterEvent | RouteConfigLoadStart | RouteConfigLoadEnd | ChildActivationStart |
ChildActivationEnd | ActivationStart | ActivationEnd | Scroll;