
committed by
Victor Berchet

parent
601fd3e305
commit
7df6f46c1c
@ -233,7 +233,7 @@ class ApplyRedirects {
|
||||
segments: UrlSegment[]): Observable<UrlSegmentGroup> {
|
||||
if (route.path === '**') {
|
||||
if (route.loadChildren) {
|
||||
return map.call(this.configLoader.load(injector, route.loadChildren), (r: any) => {
|
||||
return map.call(this.configLoader.load(injector, route), (r: any) => {
|
||||
(<any>route)._loadedConfig = r;
|
||||
return new UrlSegmentGroup(segments, {});
|
||||
});
|
||||
@ -281,7 +281,7 @@ class ApplyRedirects {
|
||||
if ((<any>route)._loadedConfig) {
|
||||
return of ((<any>route)._loadedConfig);
|
||||
} else {
|
||||
return map.call(this.configLoader.load(injector, route.loadChildren), (r: any) => {
|
||||
return map.call(this.configLoader.load(injector, route), (r: any) => {
|
||||
(<any>route)._loadedConfig = r;
|
||||
return r;
|
||||
});
|
||||
|
@ -11,7 +11,8 @@ import {Attribute, Directive, ElementRef, HostBinding, HostListener, Input, OnCh
|
||||
import {Subscription} from 'rxjs/Subscription';
|
||||
|
||||
import {QueryParamsHandling} from '../config';
|
||||
import {NavigationEnd, Router} from '../router';
|
||||
import {NavigationEnd} from '../events';
|
||||
import {Router} from '../router';
|
||||
import {ActivatedRoute} from '../router_state';
|
||||
import {UrlTree} from '../url_tree';
|
||||
|
||||
|
@ -8,13 +8,10 @@
|
||||
|
||||
import {AfterContentInit, ChangeDetectorRef, ContentChildren, Directive, ElementRef, Input, OnChanges, OnDestroy, QueryList, Renderer, SimpleChanges} from '@angular/core';
|
||||
import {Subscription} from 'rxjs/Subscription';
|
||||
|
||||
import {NavigationEnd, Router} from '../router';
|
||||
|
||||
import {NavigationEnd} from '../events';
|
||||
import {Router} from '../router';
|
||||
import {RouterLink, RouterLinkWithHref} from './router_link';
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @whatItDoes Lets you add a CSS class to an element when the link's route becomes active.
|
||||
*
|
||||
|
@ -6,8 +6,7 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {Attribute, ComponentFactory, ComponentFactoryResolver, ComponentRef, Directive, EventEmitter, Injector, OnDestroy, Output, ReflectiveInjector, ResolvedReflectiveProvider, ViewContainerRef} from '@angular/core';
|
||||
|
||||
import {Attribute, ComponentFactoryResolver, ComponentRef, Directive, EventEmitter, Injector, OnDestroy, Output, ReflectiveInjector, ResolvedReflectiveProvider, ViewContainerRef} from '@angular/core';
|
||||
import {RouterOutletMap} from '../router_outlet_map';
|
||||
import {ActivatedRoute} from '../router_state';
|
||||
import {PRIMARY_OUTLET} from '../shared';
|
||||
|
133
modules/@angular/router/src/events.ts
Normal file
133
modules/@angular/router/src/events.ts
Normal file
@ -0,0 +1,133 @@
|
||||
/**
|
||||
* @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 {RouterStateSnapshot} from './router_state';
|
||||
|
||||
/**
|
||||
* @whatItDoes Represents an event triggered when a navigation starts.
|
||||
*
|
||||
* @stable
|
||||
*/
|
||||
export class NavigationStart {
|
||||
// TODO: vsavkin: make internal
|
||||
constructor(
|
||||
/** @docsNotRequired */
|
||||
public id: number,
|
||||
/** @docsNotRequired */
|
||||
public url: string) {}
|
||||
|
||||
/** @docsNotRequired */
|
||||
toString(): string { return `NavigationStart(id: ${this.id}, url: '${this.url}')`; }
|
||||
}
|
||||
|
||||
/**
|
||||
* @whatItDoes Represents an event triggered when a navigation ends successfully.
|
||||
*
|
||||
* @stable
|
||||
*/
|
||||
export class NavigationEnd {
|
||||
// TODO: vsavkin: make internal
|
||||
constructor(
|
||||
/** @docsNotRequired */
|
||||
public id: number,
|
||||
/** @docsNotRequired */
|
||||
public url: string,
|
||||
/** @docsNotRequired */
|
||||
public urlAfterRedirects: string) {}
|
||||
|
||||
/** @docsNotRequired */
|
||||
toString(): string {
|
||||
return `NavigationEnd(id: ${this.id}, url: '${this.url}', urlAfterRedirects: '${this.urlAfterRedirects}')`;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @whatItDoes Represents an event triggered when a navigation is canceled.
|
||||
*
|
||||
* @stable
|
||||
*/
|
||||
export class NavigationCancel {
|
||||
// TODO: vsavkin: make internal
|
||||
constructor(
|
||||
/** @docsNotRequired */
|
||||
public id: number,
|
||||
/** @docsNotRequired */
|
||||
public url: string,
|
||||
/** @docsNotRequired */
|
||||
public reason: string) {}
|
||||
|
||||
/** @docsNotRequired */
|
||||
toString(): string { return `NavigationCancel(id: ${this.id}, url: '${this.url}')`; }
|
||||
}
|
||||
|
||||
/**
|
||||
* @whatItDoes Represents an event triggered when a navigation fails due to an unexpected error.
|
||||
*
|
||||
* @stable
|
||||
*/
|
||||
export class NavigationError {
|
||||
// TODO: vsavkin: make internal
|
||||
constructor(
|
||||
/** @docsNotRequired */
|
||||
public id: number,
|
||||
/** @docsNotRequired */
|
||||
public url: string,
|
||||
/** @docsNotRequired */
|
||||
public error: any) {}
|
||||
|
||||
/** @docsNotRequired */
|
||||
toString(): string {
|
||||
return `NavigationError(id: ${this.id}, url: '${this.url}', error: ${this.error})`;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @whatItDoes Represents an event triggered when routes are recognized.
|
||||
*
|
||||
* @stable
|
||||
*/
|
||||
export class RoutesRecognized {
|
||||
// TODO: vsavkin: make internal
|
||||
constructor(
|
||||
/** @docsNotRequired */
|
||||
public id: number,
|
||||
/** @docsNotRequired */
|
||||
public url: string,
|
||||
/** @docsNotRequired */
|
||||
public urlAfterRedirects: string,
|
||||
/** @docsNotRequired */
|
||||
public state: RouterStateSnapshot) {}
|
||||
|
||||
/** @docsNotRequired */
|
||||
toString(): string {
|
||||
return `RoutesRecognized(id: ${this.id}, url: '${this.url}', urlAfterRedirects: '${this.urlAfterRedirects}', state: ${this.state})`;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @whatItDoes Represents an event triggered when route is lazy loaded.
|
||||
*
|
||||
* @experimental
|
||||
*/
|
||||
export class RouteConfigLoaded {
|
||||
constructor(public route: Route) {}
|
||||
|
||||
toString(): string { return `RouteConfigLoaded(path: ${this.route.path})`; }
|
||||
}
|
||||
|
||||
/**
|
||||
* @whatItDoes Represents a router event.
|
||||
*
|
||||
* Please see {@link NavigationStart}, {@link NavigationEnd}, {@link NavigationCancel}, {@link
|
||||
* NavigationError}, {@link RoutesRecognized}, {@link RouteConfigLoaded} for more information.
|
||||
*
|
||||
* @stable
|
||||
*/
|
||||
export type Event = NavigationStart | NavigationEnd | NavigationCancel | NavigationError |
|
||||
RoutesRecognized | RouteConfigLoaded;
|
@ -11,9 +11,9 @@ export {Data, LoadChildren, LoadChildrenCallback, ResolveData, Route, Routes} fr
|
||||
export {RouterLink, RouterLinkWithHref} from './directives/router_link';
|
||||
export {RouterLinkActive} from './directives/router_link_active';
|
||||
export {RouterOutlet} from './directives/router_outlet';
|
||||
export {Event, NavigationCancel, NavigationEnd, NavigationError, NavigationStart, RouteConfigLoaded, RoutesRecognized} from './events';
|
||||
export {CanActivate, CanActivateChild, CanDeactivate, CanLoad, Resolve} from './interfaces';
|
||||
export {DetachedRouteHandle, RouteReuseStrategy} from './route_reuse_strategy';
|
||||
export {Event, NavigationCancel, NavigationEnd, NavigationError, NavigationExtras, NavigationStart, Router, RoutesRecognized} from './router';
|
||||
export {ROUTES} from './router_config_loader';
|
||||
export {ExtraOptions, ROUTER_CONFIGURATION, ROUTER_INITIALIZER, RouterModule, provideRoutes} from './router_module';
|
||||
export {RouterOutletMap} from './router_outlet_map';
|
||||
|
@ -22,10 +22,11 @@ import {mergeMap} from 'rxjs/operator/mergeMap';
|
||||
import {reduce} from 'rxjs/operator/reduce';
|
||||
|
||||
import {applyRedirects} from './apply_redirects';
|
||||
import {QueryParamsHandling, ResolveData, Routes, validateConfig} from './config';
|
||||
import {QueryParamsHandling, ResolveData, Route, Routes, validateConfig} from './config';
|
||||
import {createRouterState} from './create_router_state';
|
||||
import {createUrlTree} from './create_url_tree';
|
||||
import {RouterOutlet} from './directives/router_outlet';
|
||||
import {Event, NavigationCancel, NavigationEnd, NavigationError, NavigationStart, RouteConfigLoaded, RoutesRecognized} from './events';
|
||||
import {recognize} from './recognize';
|
||||
import {DetachedRouteHandle, DetachedRouteHandleInternal, RouteReuseStrategy} from './route_reuse_strategy';
|
||||
import {LoadedRouterConfig, RouterConfigLoader} from './router_config_loader';
|
||||
@ -151,119 +152,6 @@ export interface NavigationExtras {
|
||||
replaceUrl?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* @whatItDoes Represents an event triggered when a navigation starts.
|
||||
*
|
||||
* @stable
|
||||
*/
|
||||
export class NavigationStart {
|
||||
// TODO: vsavkin: make internal
|
||||
constructor(
|
||||
/** @docsNotRequired */
|
||||
public id: number,
|
||||
/** @docsNotRequired */
|
||||
public url: string) {}
|
||||
|
||||
/** @docsNotRequired */
|
||||
toString(): string { return `NavigationStart(id: ${this.id}, url: '${this.url}')`; }
|
||||
}
|
||||
|
||||
/**
|
||||
* @whatItDoes Represents an event triggered when a navigation ends successfully.
|
||||
*
|
||||
* @stable
|
||||
*/
|
||||
export class NavigationEnd {
|
||||
// TODO: vsavkin: make internal
|
||||
constructor(
|
||||
/** @docsNotRequired */
|
||||
public id: number,
|
||||
/** @docsNotRequired */
|
||||
public url: string,
|
||||
/** @docsNotRequired */
|
||||
public urlAfterRedirects: string) {}
|
||||
|
||||
/** @docsNotRequired */
|
||||
toString(): string {
|
||||
return `NavigationEnd(id: ${this.id}, url: '${this.url}', urlAfterRedirects: '${this.urlAfterRedirects}')`;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @whatItDoes Represents an event triggered when a navigation is canceled.
|
||||
*
|
||||
* @stable
|
||||
*/
|
||||
export class NavigationCancel {
|
||||
// TODO: vsavkin: make internal
|
||||
constructor(
|
||||
/** @docsNotRequired */
|
||||
public id: number,
|
||||
/** @docsNotRequired */
|
||||
public url: string,
|
||||
/** @docsNotRequired */
|
||||
public reason: string) {}
|
||||
|
||||
/** @docsNotRequired */
|
||||
toString(): string { return `NavigationCancel(id: ${this.id}, url: '${this.url}')`; }
|
||||
}
|
||||
|
||||
/**
|
||||
* @whatItDoes Represents an event triggered when a navigation fails due to an unexpected error.
|
||||
*
|
||||
* @stable
|
||||
*/
|
||||
export class NavigationError {
|
||||
// TODO: vsavkin: make internal
|
||||
constructor(
|
||||
/** @docsNotRequired */
|
||||
public id: number,
|
||||
/** @docsNotRequired */
|
||||
public url: string,
|
||||
/** @docsNotRequired */
|
||||
public error: any) {}
|
||||
|
||||
/** @docsNotRequired */
|
||||
toString(): string {
|
||||
return `NavigationError(id: ${this.id}, url: '${this.url}', error: ${this.error})`;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @whatItDoes Represents an event triggered when routes are recognized.
|
||||
*
|
||||
* @stable
|
||||
*/
|
||||
export class RoutesRecognized {
|
||||
// TODO: vsavkin: make internal
|
||||
constructor(
|
||||
/** @docsNotRequired */
|
||||
public id: number,
|
||||
/** @docsNotRequired */
|
||||
public url: string,
|
||||
/** @docsNotRequired */
|
||||
public urlAfterRedirects: string,
|
||||
/** @docsNotRequired */
|
||||
public state: RouterStateSnapshot) {}
|
||||
|
||||
/** @docsNotRequired */
|
||||
toString(): string {
|
||||
return `RoutesRecognized(id: ${this.id}, url: '${this.url}', urlAfterRedirects: '${this.urlAfterRedirects}', state: ${this.state})`;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @whatItDoes Represents a router event.
|
||||
*
|
||||
* Please see {@link NavigationStart}, {@link NavigationEnd}, {@link NavigationCancel}, {@link
|
||||
* NavigationError},
|
||||
* {@link RoutesRecognized} for more information.
|
||||
*
|
||||
* @stable
|
||||
*/
|
||||
export type Event =
|
||||
NavigationStart | NavigationEnd | NavigationCancel | NavigationError | RoutesRecognized;
|
||||
|
||||
/**
|
||||
* @whatItDoes Error handler that is invoked when a navigation errors.
|
||||
*
|
||||
@ -320,7 +208,8 @@ export class Router {
|
||||
private rawUrlTree: UrlTree;
|
||||
|
||||
private navigations = new BehaviorSubject<NavigationParams>(null);
|
||||
private routerEvents = new Subject<Event>();
|
||||
/** @internal */
|
||||
routerEvents = new Subject<Event>();
|
||||
|
||||
private currentRouterState: RouterState;
|
||||
private locationSubscription: Subscription;
|
||||
@ -357,7 +246,8 @@ export class Router {
|
||||
this.resetConfig(config);
|
||||
this.currentUrlTree = createEmptyUrlTree();
|
||||
this.rawUrlTree = this.currentUrlTree;
|
||||
this.configLoader = new RouterConfigLoader(loader, compiler);
|
||||
this.configLoader = new RouterConfigLoader(
|
||||
loader, compiler, (r: Route) => this.routerEvents.next(new RouteConfigLoaded(r)));
|
||||
this.currentRouterState = createEmptyState(this.currentUrlTree, this.rootComponentType);
|
||||
this.processNavigations();
|
||||
}
|
||||
|
@ -12,11 +12,9 @@ import {fromPromise} from 'rxjs/observable/fromPromise';
|
||||
import {of } from 'rxjs/observable/of';
|
||||
import {map} from 'rxjs/operator/map';
|
||||
import {mergeMap} from 'rxjs/operator/mergeMap';
|
||||
|
||||
import {LoadChildren, Route} from './config';
|
||||
import {flatten, wrapIntoObservable} from './utils/collection';
|
||||
|
||||
|
||||
/**
|
||||
* @docsNotRequired
|
||||
* @experimental
|
||||
@ -30,14 +28,18 @@ export class LoadedRouterConfig {
|
||||
}
|
||||
|
||||
export class RouterConfigLoader {
|
||||
constructor(private loader: NgModuleFactoryLoader, private compiler: Compiler) {}
|
||||
constructor(
|
||||
private loader: NgModuleFactoryLoader, private compiler: Compiler,
|
||||
private onLoadListener: (r: Route) => void) {}
|
||||
|
||||
load(parentInjector: Injector, loadChildren: LoadChildren): Observable<LoadedRouterConfig> {
|
||||
return map.call(this.loadModuleFactory(loadChildren), (r: NgModuleFactory<any>) => {
|
||||
const ref = r.create(parentInjector);
|
||||
const injectorFactory = (parent: Injector) => r.create(parent).injector;
|
||||
load(parentInjector: Injector, route: Route): Observable<LoadedRouterConfig> {
|
||||
const moduleFactory$ = this.loadModuleFactory(route.loadChildren);
|
||||
return map.call(moduleFactory$, (factory: NgModuleFactory<any>) => {
|
||||
const module = factory.create(parentInjector);
|
||||
const injectorFactory = (parent: Injector) => factory.create(parent).injector;
|
||||
this.onLoadListener(route);
|
||||
return new LoadedRouterConfig(
|
||||
flatten(ref.injector.get(ROUTES)), ref.injector, ref.componentFactoryResolver,
|
||||
flatten(module.injector.get(ROUTES)), module.injector, module.componentFactoryResolver,
|
||||
injectorFactory);
|
||||
});
|
||||
}
|
||||
|
@ -16,9 +16,9 @@ import {concatMap} from 'rxjs/operator/concatMap';
|
||||
import {filter} from 'rxjs/operator/filter';
|
||||
import {mergeAll} from 'rxjs/operator/mergeAll';
|
||||
import {mergeMap} from 'rxjs/operator/mergeMap';
|
||||
|
||||
import {Route, Routes} from './config';
|
||||
import {NavigationEnd, Router} from './router';
|
||||
import {NavigationEnd, RouteConfigLoaded} from './events';
|
||||
import {Router} from './router';
|
||||
import {RouterConfigLoader} from './router_config_loader';
|
||||
|
||||
/**
|
||||
@ -80,17 +80,18 @@ export class RouterPreloader {
|
||||
constructor(
|
||||
private router: Router, moduleLoader: NgModuleFactoryLoader, compiler: Compiler,
|
||||
private injector: Injector, private preloadingStrategy: PreloadingStrategy) {
|
||||
this.loader = new RouterConfigLoader(moduleLoader, compiler);
|
||||
this.loader = new RouterConfigLoader(
|
||||
moduleLoader, compiler, (r: Route) => router.routerEvents.next(new RouteConfigLoaded(r)));
|
||||
};
|
||||
|
||||
setUpPreloading(): void {
|
||||
const navigations = filter.call(this.router.events, (e: any) => e instanceof NavigationEnd);
|
||||
this.subscription = concatMap.call(navigations, () => this.preload()).subscribe((v: any) => {});
|
||||
this.subscription = concatMap.call(navigations, () => this.preload()).subscribe(() => {});
|
||||
}
|
||||
|
||||
preload(): Observable<any> { return this.processRoutes(this.injector, this.router.config); }
|
||||
|
||||
ngOnDestroy() { this.subscription.unsubscribe(); }
|
||||
ngOnDestroy(): void { this.subscription.unsubscribe(); }
|
||||
|
||||
private processRoutes(injector: Injector, routes: Routes): Observable<void> {
|
||||
const res: Observable<any>[] = [];
|
||||
@ -114,7 +115,7 @@ export class RouterPreloader {
|
||||
|
||||
private preloadConfig(injector: Injector, route: Route): Observable<void> {
|
||||
return this.preloadingStrategy.preload(route, () => {
|
||||
const loaded = this.loader.load(injector, route.loadChildren);
|
||||
const loaded = this.loader.load(injector, route);
|
||||
return mergeMap.call(loaded, (config: any): any => {
|
||||
const c: any = route;
|
||||
c._loadedConfig = config;
|
||||
|
Reference in New Issue
Block a user