refactor(router): cleanup & simplification (#15436)
This commit is contained in:
parent
910c0d9ee7
commit
d58a242fe7
|
@ -162,43 +162,43 @@ export function checkAndUpdateDirectiveInline(
|
||||||
if (bindLen > 0 && checkBinding(view, def, 0, v0)) {
|
if (bindLen > 0 && checkBinding(view, def, 0, v0)) {
|
||||||
changed = true;
|
changed = true;
|
||||||
changes = updateProp(view, providerData, def, 0, v0, changes);
|
changes = updateProp(view, providerData, def, 0, v0, changes);
|
||||||
};
|
}
|
||||||
if (bindLen > 1 && checkBinding(view, def, 1, v1)) {
|
if (bindLen > 1 && checkBinding(view, def, 1, v1)) {
|
||||||
changed = true;
|
changed = true;
|
||||||
changes = updateProp(view, providerData, def, 1, v1, changes);
|
changes = updateProp(view, providerData, def, 1, v1, changes);
|
||||||
};
|
}
|
||||||
if (bindLen > 2 && checkBinding(view, def, 2, v2)) {
|
if (bindLen > 2 && checkBinding(view, def, 2, v2)) {
|
||||||
changed = true;
|
changed = true;
|
||||||
changes = updateProp(view, providerData, def, 2, v2, changes);
|
changes = updateProp(view, providerData, def, 2, v2, changes);
|
||||||
};
|
}
|
||||||
if (bindLen > 3 && checkBinding(view, def, 3, v3)) {
|
if (bindLen > 3 && checkBinding(view, def, 3, v3)) {
|
||||||
changed = true;
|
changed = true;
|
||||||
changes = updateProp(view, providerData, def, 3, v3, changes);
|
changes = updateProp(view, providerData, def, 3, v3, changes);
|
||||||
};
|
}
|
||||||
if (bindLen > 4 && checkBinding(view, def, 4, v4)) {
|
if (bindLen > 4 && checkBinding(view, def, 4, v4)) {
|
||||||
changed = true;
|
changed = true;
|
||||||
changes = updateProp(view, providerData, def, 4, v4, changes);
|
changes = updateProp(view, providerData, def, 4, v4, changes);
|
||||||
};
|
}
|
||||||
if (bindLen > 5 && checkBinding(view, def, 5, v5)) {
|
if (bindLen > 5 && checkBinding(view, def, 5, v5)) {
|
||||||
changed = true;
|
changed = true;
|
||||||
changes = updateProp(view, providerData, def, 5, v5, changes);
|
changes = updateProp(view, providerData, def, 5, v5, changes);
|
||||||
};
|
}
|
||||||
if (bindLen > 6 && checkBinding(view, def, 6, v6)) {
|
if (bindLen > 6 && checkBinding(view, def, 6, v6)) {
|
||||||
changed = true;
|
changed = true;
|
||||||
changes = updateProp(view, providerData, def, 6, v6, changes);
|
changes = updateProp(view, providerData, def, 6, v6, changes);
|
||||||
};
|
}
|
||||||
if (bindLen > 7 && checkBinding(view, def, 7, v7)) {
|
if (bindLen > 7 && checkBinding(view, def, 7, v7)) {
|
||||||
changed = true;
|
changed = true;
|
||||||
changes = updateProp(view, providerData, def, 7, v7, changes);
|
changes = updateProp(view, providerData, def, 7, v7, changes);
|
||||||
};
|
}
|
||||||
if (bindLen > 8 && checkBinding(view, def, 8, v8)) {
|
if (bindLen > 8 && checkBinding(view, def, 8, v8)) {
|
||||||
changed = true;
|
changed = true;
|
||||||
changes = updateProp(view, providerData, def, 8, v8, changes);
|
changes = updateProp(view, providerData, def, 8, v8, changes);
|
||||||
};
|
}
|
||||||
if (bindLen > 9 && checkBinding(view, def, 9, v9)) {
|
if (bindLen > 9 && checkBinding(view, def, 9, v9)) {
|
||||||
changed = true;
|
changed = true;
|
||||||
changes = updateProp(view, providerData, def, 9, v9, changes);
|
changes = updateProp(view, providerData, def, 9, v9, changes);
|
||||||
};
|
}
|
||||||
if (changes) {
|
if (changes) {
|
||||||
directive.ngOnChanges(changes);
|
directive.ngOnChanges(changes);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ import {map} from 'rxjs/operator/map';
|
||||||
import {mergeMap} from 'rxjs/operator/mergeMap';
|
import {mergeMap} from 'rxjs/operator/mergeMap';
|
||||||
import {EmptyError} from 'rxjs/util/EmptyError';
|
import {EmptyError} from 'rxjs/util/EmptyError';
|
||||||
|
|
||||||
import {Route, Routes} from './config';
|
import {InternalRoute, Route, Routes} from './config';
|
||||||
import {LoadedRouterConfig, RouterConfigLoader} from './router_config_loader';
|
import {LoadedRouterConfig, RouterConfigLoader} from './router_config_loader';
|
||||||
import {PRIMARY_OUTLET, Params, defaultUrlMatcher, navigationCancelingError} from './shared';
|
import {PRIMARY_OUTLET, Params, defaultUrlMatcher, navigationCancelingError} from './shared';
|
||||||
import {UrlSegment, UrlSegmentGroup, UrlSerializer, UrlTree} from './url_tree';
|
import {UrlSegment, UrlSegmentGroup, UrlSerializer, UrlTree} from './url_tree';
|
||||||
|
@ -241,13 +241,13 @@ class ApplyRedirects {
|
||||||
}
|
}
|
||||||
|
|
||||||
private matchSegmentAgainstRoute(
|
private matchSegmentAgainstRoute(
|
||||||
ngModule: NgModuleRef<any>, rawSegmentGroup: UrlSegmentGroup, route: Route,
|
ngModule: NgModuleRef<any>, rawSegmentGroup: UrlSegmentGroup, route: InternalRoute,
|
||||||
segments: UrlSegment[]): Observable<UrlSegmentGroup> {
|
segments: UrlSegment[]): Observable<UrlSegmentGroup> {
|
||||||
if (route.path === '**') {
|
if (route.path === '**') {
|
||||||
if (route.loadChildren) {
|
if (route.loadChildren) {
|
||||||
return map.call(
|
return map.call(
|
||||||
this.configLoader.load(ngModule.injector, route), (cfg: LoadedRouterConfig) => {
|
this.configLoader.load(ngModule.injector, route), (cfg: LoadedRouterConfig) => {
|
||||||
(<any>route)._loadedConfig = cfg;
|
route._loadedConfig = cfg;
|
||||||
return new UrlSegmentGroup(segments, {});
|
return new UrlSegmentGroup(segments, {});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -286,7 +286,8 @@ class ApplyRedirects {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private getChildConfig(ngModule: NgModuleRef<any>, route: Route): Observable<LoadedRouterConfig> {
|
private getChildConfig(ngModule: NgModuleRef<any>, route: InternalRoute):
|
||||||
|
Observable<LoadedRouterConfig> {
|
||||||
if (route.children) {
|
if (route.children) {
|
||||||
// The children belong to the same module
|
// The children belong to the same module
|
||||||
return of (new LoadedRouterConfig(route.children, ngModule));
|
return of (new LoadedRouterConfig(route.children, ngModule));
|
||||||
|
@ -302,7 +303,7 @@ class ApplyRedirects {
|
||||||
if (shouldLoad) {
|
if (shouldLoad) {
|
||||||
return map.call(
|
return map.call(
|
||||||
this.configLoader.load(ngModule.injector, route), (cfg: LoadedRouterConfig) => {
|
this.configLoader.load(ngModule.injector, route), (cfg: LoadedRouterConfig) => {
|
||||||
(<any>route)._loadedConfig = cfg;
|
route._loadedConfig = cfg;
|
||||||
return cfg;
|
return cfg;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
import {NgModuleFactory, Type} from '@angular/core';
|
import {NgModuleFactory, Type} from '@angular/core';
|
||||||
import {Observable} from 'rxjs/Observable';
|
import {Observable} from 'rxjs/Observable';
|
||||||
|
|
||||||
import {ActivatedRouteSnapshot, RouterStateSnapshot} from './router_state';
|
|
||||||
import {PRIMARY_OUTLET} from './shared';
|
import {PRIMARY_OUTLET} from './shared';
|
||||||
import {UrlSegment, UrlSegmentGroup} from './url_tree';
|
import {UrlSegment, UrlSegmentGroup} from './url_tree';
|
||||||
|
|
||||||
|
@ -362,6 +361,11 @@ export interface Route {
|
||||||
runGuardsAndResolvers?: RunGuardsAndResolvers;
|
runGuardsAndResolvers?: RunGuardsAndResolvers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface InternalRoute extends Route {
|
||||||
|
// `LoadedRouterConfig` loaded via a Route `loadChildren`
|
||||||
|
_loadedConfig?: any;
|
||||||
|
}
|
||||||
|
|
||||||
export function validateConfig(config: Routes, parentPath: string = ''): void {
|
export function validateConfig(config: Routes, parentPath: string = ''): void {
|
||||||
// forEach doesn't iterate undefined values
|
// forEach doesn't iterate undefined values
|
||||||
for (let i = 0; i < config.length; i++) {
|
for (let i = 0; i < config.length; i++) {
|
||||||
|
|
|
@ -7,6 +7,5 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export {ROUTER_PROVIDERS as ɵROUTER_PROVIDERS} from './router_module';
|
export {ROUTER_PROVIDERS as ɵROUTER_PROVIDERS} from './router_module';
|
||||||
export {flatten as ɵflatten} from './utils/collection';
|
export {flatten as ɵflatten} from './utils/collection';
|
||||||
|
|
|
@ -11,7 +11,7 @@ import {Observable} from 'rxjs/Observable';
|
||||||
import {Observer} from 'rxjs/Observer';
|
import {Observer} from 'rxjs/Observer';
|
||||||
import {of } from 'rxjs/observable/of';
|
import {of } from 'rxjs/observable/of';
|
||||||
|
|
||||||
import {Data, ResolveData, Route, Routes} from './config';
|
import {Data, InternalRoute, ResolveData, Route, Routes} from './config';
|
||||||
import {ActivatedRouteSnapshot, RouterStateSnapshot, inheritedParamsDataResolve} from './router_state';
|
import {ActivatedRouteSnapshot, RouterStateSnapshot, inheritedParamsDataResolve} from './router_state';
|
||||||
import {PRIMARY_OUTLET, defaultUrlMatcher} from './shared';
|
import {PRIMARY_OUTLET, defaultUrlMatcher} from './shared';
|
||||||
import {UrlSegment, UrlSegmentGroup, UrlTree, mapChildrenIntoArray} from './url_tree';
|
import {UrlSegment, UrlSegmentGroup, UrlTree, mapChildrenIntoArray} from './url_tree';
|
||||||
|
@ -66,9 +66,9 @@ class Recognizer {
|
||||||
TreeNode<ActivatedRouteSnapshot>[] {
|
TreeNode<ActivatedRouteSnapshot>[] {
|
||||||
if (segmentGroup.segments.length === 0 && segmentGroup.hasChildren()) {
|
if (segmentGroup.segments.length === 0 && segmentGroup.hasChildren()) {
|
||||||
return this.processChildren(config, segmentGroup);
|
return this.processChildren(config, segmentGroup);
|
||||||
} else {
|
|
||||||
return this.processSegment(config, segmentGroup, segmentGroup.segments, outlet);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return this.processSegment(config, segmentGroup, segmentGroup.segments, outlet);
|
||||||
}
|
}
|
||||||
|
|
||||||
processChildren(config: Route[], segmentGroup: UrlSegmentGroup):
|
processChildren(config: Route[], segmentGroup: UrlSegmentGroup):
|
||||||
|
@ -92,9 +92,9 @@ class Recognizer {
|
||||||
}
|
}
|
||||||
if (this.noLeftoversInUrl(segmentGroup, segments, outlet)) {
|
if (this.noLeftoversInUrl(segmentGroup, segments, outlet)) {
|
||||||
return [];
|
return [];
|
||||||
} else {
|
|
||||||
throw new NoMatch();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
throw new NoMatch();
|
||||||
}
|
}
|
||||||
|
|
||||||
private noLeftoversInUrl(segmentGroup: UrlSegmentGroup, segments: UrlSegment[], outlet: string):
|
private noLeftoversInUrl(segmentGroup: UrlSegmentGroup, segments: UrlSegment[], outlet: string):
|
||||||
|
@ -107,7 +107,7 @@ class Recognizer {
|
||||||
outlet: string): TreeNode<ActivatedRouteSnapshot>[] {
|
outlet: string): TreeNode<ActivatedRouteSnapshot>[] {
|
||||||
if (route.redirectTo) throw new NoMatch();
|
if (route.redirectTo) throw new NoMatch();
|
||||||
|
|
||||||
if ((route.outlet ? route.outlet : PRIMARY_OUTLET) !== outlet) throw new NoMatch();
|
if ((route.outlet || PRIMARY_OUTLET) !== outlet) throw new NoMatch();
|
||||||
|
|
||||||
if (route.path === '**') {
|
if (route.path === '**') {
|
||||||
const params = segments.length > 0 ? last(segments).parameters : {};
|
const params = segments.length > 0 ? last(segments).parameters : {};
|
||||||
|
@ -135,15 +135,14 @@ class Recognizer {
|
||||||
if (slicedSegments.length === 0 && segmentGroup.hasChildren()) {
|
if (slicedSegments.length === 0 && segmentGroup.hasChildren()) {
|
||||||
const children = this.processChildren(childConfig, segmentGroup);
|
const children = this.processChildren(childConfig, segmentGroup);
|
||||||
return [new TreeNode<ActivatedRouteSnapshot>(snapshot, children)];
|
return [new TreeNode<ActivatedRouteSnapshot>(snapshot, children)];
|
||||||
|
|
||||||
} else if (childConfig.length === 0 && slicedSegments.length === 0) {
|
|
||||||
return [new TreeNode<ActivatedRouteSnapshot>(snapshot, [])];
|
|
||||||
|
|
||||||
} else {
|
|
||||||
const children =
|
|
||||||
this.processSegment(childConfig, segmentGroup, slicedSegments, PRIMARY_OUTLET);
|
|
||||||
return [new TreeNode<ActivatedRouteSnapshot>(snapshot, children)];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (childConfig.length === 0 && slicedSegments.length === 0) {
|
||||||
|
return [new TreeNode<ActivatedRouteSnapshot>(snapshot, [])];
|
||||||
|
}
|
||||||
|
|
||||||
|
const children = this.processSegment(childConfig, segmentGroup, slicedSegments, PRIMARY_OUTLET);
|
||||||
|
return [new TreeNode<ActivatedRouteSnapshot>(snapshot, children)];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,23 +154,25 @@ function sortActivatedRouteSnapshots(nodes: TreeNode<ActivatedRouteSnapshot>[]):
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function getChildConfig(route: Route): Route[] {
|
function getChildConfig(route: InternalRoute): Route[] {
|
||||||
if (route.children) {
|
if (route.children) {
|
||||||
return route.children;
|
return route.children;
|
||||||
} else if (route.loadChildren) {
|
|
||||||
return (<any>route)._loadedConfig.routes;
|
|
||||||
} else {
|
|
||||||
return [];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (route.loadChildren) {
|
||||||
|
return route._loadedConfig.routes;
|
||||||
|
}
|
||||||
|
|
||||||
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
function match(segmentGroup: UrlSegmentGroup, route: Route, segments: UrlSegment[]) {
|
function match(segmentGroup: UrlSegmentGroup, route: Route, segments: UrlSegment[]) {
|
||||||
if (route.path === '') {
|
if (route.path === '') {
|
||||||
if (route.pathMatch === 'full' && (segmentGroup.hasChildren() || segments.length > 0)) {
|
if (route.pathMatch === 'full' && (segmentGroup.hasChildren() || segments.length > 0)) {
|
||||||
throw new NoMatch();
|
throw new NoMatch();
|
||||||
} else {
|
|
||||||
return {consumedSegments: [], lastChild: 0, parameters: {}};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return {consumedSegments: [], lastChild: 0, parameters: {}};
|
||||||
}
|
}
|
||||||
|
|
||||||
const matcher = route.matcher || defaultUrlMatcher;
|
const matcher = route.matcher || defaultUrlMatcher;
|
||||||
|
@ -228,9 +229,9 @@ function split(
|
||||||
s._sourceSegment = segmentGroup;
|
s._sourceSegment = segmentGroup;
|
||||||
s._segmentIndexShift = consumedSegments.length;
|
s._segmentIndexShift = consumedSegments.length;
|
||||||
return {segmentGroup: s, slicedSegments: []};
|
return {segmentGroup: s, slicedSegments: []};
|
||||||
|
}
|
||||||
|
|
||||||
} else if (
|
if (slicedSegments.length === 0 &&
|
||||||
slicedSegments.length === 0 &&
|
|
||||||
containsEmptyPathMatches(segmentGroup, slicedSegments, config)) {
|
containsEmptyPathMatches(segmentGroup, slicedSegments, config)) {
|
||||||
const s = new UrlSegmentGroup(
|
const s = new UrlSegmentGroup(
|
||||||
segmentGroup.segments, addEmptyPathsToChildrenIfNeeded(
|
segmentGroup.segments, addEmptyPathsToChildrenIfNeeded(
|
||||||
|
@ -238,13 +239,12 @@ function split(
|
||||||
s._sourceSegment = segmentGroup;
|
s._sourceSegment = segmentGroup;
|
||||||
s._segmentIndexShift = consumedSegments.length;
|
s._segmentIndexShift = consumedSegments.length;
|
||||||
return {segmentGroup: s, slicedSegments};
|
return {segmentGroup: s, slicedSegments};
|
||||||
|
|
||||||
} else {
|
|
||||||
const s = new UrlSegmentGroup(segmentGroup.segments, segmentGroup.children);
|
|
||||||
s._sourceSegment = segmentGroup;
|
|
||||||
s._segmentIndexShift = consumedSegments.length;
|
|
||||||
return {segmentGroup: s, slicedSegments};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const s = new UrlSegmentGroup(segmentGroup.segments, segmentGroup.children);
|
||||||
|
s._sourceSegment = segmentGroup;
|
||||||
|
s._segmentIndexShift = consumedSegments.length;
|
||||||
|
return {segmentGroup: s, slicedSegments};
|
||||||
}
|
}
|
||||||
|
|
||||||
function addEmptyPathsToChildrenIfNeeded(
|
function addEmptyPathsToChildrenIfNeeded(
|
||||||
|
@ -283,33 +283,32 @@ function createChildrenForEmptyPaths(
|
||||||
|
|
||||||
function containsEmptyPathMatchesWithNamedOutlets(
|
function containsEmptyPathMatchesWithNamedOutlets(
|
||||||
segmentGroup: UrlSegmentGroup, slicedSegments: UrlSegment[], routes: Route[]): boolean {
|
segmentGroup: UrlSegmentGroup, slicedSegments: UrlSegment[], routes: Route[]): boolean {
|
||||||
return routes
|
return routes.some(
|
||||||
.filter(
|
r => emptyPathMatch(segmentGroup, slicedSegments, r) && getOutlet(r) !== PRIMARY_OUTLET);
|
||||||
r => emptyPathMatch(segmentGroup, slicedSegments, r) &&
|
|
||||||
getOutlet(r) !== PRIMARY_OUTLET)
|
|
||||||
.length > 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function containsEmptyPathMatches(
|
function containsEmptyPathMatches(
|
||||||
segmentGroup: UrlSegmentGroup, slicedSegments: UrlSegment[], routes: Route[]): boolean {
|
segmentGroup: UrlSegmentGroup, slicedSegments: UrlSegment[], routes: Route[]): boolean {
|
||||||
return routes.filter(r => emptyPathMatch(segmentGroup, slicedSegments, r)).length > 0;
|
return routes.some(r => emptyPathMatch(segmentGroup, slicedSegments, r));
|
||||||
}
|
}
|
||||||
|
|
||||||
function emptyPathMatch(
|
function emptyPathMatch(
|
||||||
segmentGroup: UrlSegmentGroup, slicedSegments: UrlSegment[], r: Route): boolean {
|
segmentGroup: UrlSegmentGroup, slicedSegments: UrlSegment[], r: Route): boolean {
|
||||||
if ((segmentGroup.hasChildren() || slicedSegments.length > 0) && r.pathMatch === 'full')
|
if ((segmentGroup.hasChildren() || slicedSegments.length > 0) && r.pathMatch === 'full') {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return r.path === '' && r.redirectTo === undefined;
|
return r.path === '' && r.redirectTo === undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getOutlet(route: Route): string {
|
function getOutlet(route: Route): string {
|
||||||
return route.outlet ? route.outlet : PRIMARY_OUTLET;
|
return route.outlet || PRIMARY_OUTLET;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getData(route: Route): Data {
|
function getData(route: Route): Data {
|
||||||
return route.data ? route.data : {};
|
return route.data || {};
|
||||||
}
|
}
|
||||||
|
|
||||||
function getResolve(route: Route): ResolveData {
|
function getResolve(route: Route): ResolveData {
|
||||||
return route.resolve ? route.resolve : {};
|
return route.resolve || {};
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ import {mergeMap} from 'rxjs/operator/mergeMap';
|
||||||
import {reduce} from 'rxjs/operator/reduce';
|
import {reduce} from 'rxjs/operator/reduce';
|
||||||
|
|
||||||
import {applyRedirects} from './apply_redirects';
|
import {applyRedirects} from './apply_redirects';
|
||||||
import {QueryParamsHandling, ResolveData, Route, Routes, RunGuardsAndResolvers, validateConfig} from './config';
|
import {InternalRoute, QueryParamsHandling, ResolveData, Route, Routes, RunGuardsAndResolvers, validateConfig} from './config';
|
||||||
import {createRouterState} from './create_router_state';
|
import {createRouterState} from './create_router_state';
|
||||||
import {createUrlTree} from './create_url_tree';
|
import {createUrlTree} from './create_url_tree';
|
||||||
import {RouterOutlet} from './directives/router_outlet';
|
import {RouterOutlet} from './directives/router_outlet';
|
||||||
|
@ -806,15 +806,15 @@ export class PreActivation {
|
||||||
private traverseChildRoutes(
|
private traverseChildRoutes(
|
||||||
futureNode: TreeNode<ActivatedRouteSnapshot>, currNode: TreeNode<ActivatedRouteSnapshot>,
|
futureNode: TreeNode<ActivatedRouteSnapshot>, currNode: TreeNode<ActivatedRouteSnapshot>,
|
||||||
outletMap: RouterOutletMap, futurePath: ActivatedRouteSnapshot[]): void {
|
outletMap: RouterOutletMap, futurePath: ActivatedRouteSnapshot[]): void {
|
||||||
const prevChildren: {[key: string]: any} = nodeChildrenAsMap(currNode);
|
const prevChildren = nodeChildrenAsMap(currNode);
|
||||||
|
|
||||||
futureNode.children.forEach(c => {
|
futureNode.children.forEach(c => {
|
||||||
this.traverseRoutes(c, prevChildren[c.value.outlet], outletMap, futurePath.concat([c.value]));
|
this.traverseRoutes(c, prevChildren[c.value.outlet], outletMap, futurePath.concat([c.value]));
|
||||||
delete prevChildren[c.value.outlet];
|
delete prevChildren[c.value.outlet];
|
||||||
});
|
});
|
||||||
forEach(
|
forEach(
|
||||||
prevChildren,
|
prevChildren, (v: TreeNode<ActivatedRouteSnapshot>, k: string) =>
|
||||||
(v: any, k: string) => this.deactiveRouteAndItsChildren(v, outletMap._outlets[k]));
|
this.deactiveRouteAndItsChildren(v, outletMap._outlets[k]));
|
||||||
}
|
}
|
||||||
|
|
||||||
private traverseRoutes(
|
private traverseRoutes(
|
||||||
|
@ -881,10 +881,10 @@ export class PreActivation {
|
||||||
|
|
||||||
private deactiveRouteAndItsChildren(
|
private deactiveRouteAndItsChildren(
|
||||||
route: TreeNode<ActivatedRouteSnapshot>, outlet: RouterOutlet): void {
|
route: TreeNode<ActivatedRouteSnapshot>, outlet: RouterOutlet): void {
|
||||||
const prevChildren: {[key: string]: any} = nodeChildrenAsMap(route);
|
const prevChildren = nodeChildrenAsMap(route);
|
||||||
const r = route.value;
|
const r = route.value;
|
||||||
|
|
||||||
forEach(prevChildren, (v: any, k: string) => {
|
forEach(prevChildren, (v: TreeNode<ActivatedRouteSnapshot>, k: string) => {
|
||||||
if (!r.component) {
|
if (!r.component) {
|
||||||
this.deactiveRouteAndItsChildren(v, outlet);
|
this.deactiveRouteAndItsChildren(v, outlet);
|
||||||
} else if (!!outlet) {
|
} else if (!!outlet) {
|
||||||
|
@ -1167,33 +1167,34 @@ function advanceActivatedRouteNodeAndItsChildren(node: TreeNode<ActivatedRoute>)
|
||||||
}
|
}
|
||||||
|
|
||||||
function parentLoadedConfig(snapshot: ActivatedRouteSnapshot): LoadedRouterConfig {
|
function parentLoadedConfig(snapshot: ActivatedRouteSnapshot): LoadedRouterConfig {
|
||||||
let s = snapshot.parent;
|
for (let s = snapshot.parent; s; s = s.parent) {
|
||||||
while (s) {
|
const route: InternalRoute = s._routeConfig;
|
||||||
const c: any = s._routeConfig;
|
if (route && route._loadedConfig) return route._loadedConfig;
|
||||||
if (c && c._loadedConfig) return c._loadedConfig;
|
if (route && route.component) return null;
|
||||||
if (c && c.component) return null;
|
|
||||||
s = s.parent;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function closestLoadedConfig(snapshot: ActivatedRouteSnapshot): LoadedRouterConfig {
|
function closestLoadedConfig(snapshot: ActivatedRouteSnapshot): LoadedRouterConfig {
|
||||||
if (!snapshot) return null;
|
if (!snapshot) return null;
|
||||||
|
|
||||||
let s = snapshot.parent;
|
for (let s = snapshot.parent; s; s = s.parent) {
|
||||||
while (s) {
|
const route: InternalRoute = s._routeConfig;
|
||||||
const c: any = s._routeConfig;
|
if (route && route._loadedConfig) return route._loadedConfig;
|
||||||
if (c && c._loadedConfig) return c._loadedConfig;
|
|
||||||
s = s.parent;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function nodeChildrenAsMap(node: TreeNode<any>) {
|
function nodeChildrenAsMap<T extends{outlet: string}>(node: TreeNode<T>) {
|
||||||
return node ? node.children.reduce((m: any, c: TreeNode<any>) => {
|
const map: {[key: string]: TreeNode<T>} = {};
|
||||||
m[c.value.outlet] = c;
|
|
||||||
return m;
|
if (node) {
|
||||||
}, {}) : {};
|
node.children.forEach(child => map[child.value.outlet] = child);
|
||||||
|
}
|
||||||
|
|
||||||
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getOutlet(outletMap: RouterOutletMap, route: ActivatedRoute): RouterOutlet {
|
function getOutlet(outletMap: RouterOutletMap, route: ActivatedRoute): RouterOutlet {
|
||||||
|
|
|
@ -16,7 +16,7 @@ import {concatMap} from 'rxjs/operator/concatMap';
|
||||||
import {filter} from 'rxjs/operator/filter';
|
import {filter} from 'rxjs/operator/filter';
|
||||||
import {mergeAll} from 'rxjs/operator/mergeAll';
|
import {mergeAll} from 'rxjs/operator/mergeAll';
|
||||||
import {mergeMap} from 'rxjs/operator/mergeMap';
|
import {mergeMap} from 'rxjs/operator/mergeMap';
|
||||||
import {Route, Routes} from './config';
|
import {InternalRoute, Route, Routes} from './config';
|
||||||
import {NavigationEnd, RouteConfigLoadEnd, RouteConfigLoadStart} from './events';
|
import {NavigationEnd, RouteConfigLoadEnd, RouteConfigLoadStart} from './events';
|
||||||
import {Router} from './router';
|
import {Router} from './router';
|
||||||
import {RouterConfigLoader} from './router_config_loader';
|
import {RouterConfigLoader} from './router_config_loader';
|
||||||
|
@ -100,30 +100,30 @@ export class RouterPreloader {
|
||||||
|
|
||||||
private processRoutes(ngModule: NgModuleRef<any>, routes: Routes): Observable<void> {
|
private processRoutes(ngModule: NgModuleRef<any>, routes: Routes): Observable<void> {
|
||||||
const res: Observable<any>[] = [];
|
const res: Observable<any>[] = [];
|
||||||
for (const c of routes) {
|
for (const r of routes) {
|
||||||
|
const route: InternalRoute = r;
|
||||||
// we already have the config loaded, just recurse
|
// we already have the config loaded, just recurse
|
||||||
if (c.loadChildren && !c.canLoad && (<any>c)._loadedConfig) {
|
if (route.loadChildren && !route.canLoad && route._loadedConfig) {
|
||||||
const childConfig = (<any>c)._loadedConfig;
|
const childConfig = route._loadedConfig;
|
||||||
res.push(this.processRoutes(childConfig.module, childConfig.routes));
|
res.push(this.processRoutes(ngModule, childConfig.routes));
|
||||||
|
|
||||||
// no config loaded, fetch the config
|
// no config loaded, fetch the config
|
||||||
} else if (c.loadChildren && !c.canLoad) {
|
} else if (route.loadChildren && !route.canLoad) {
|
||||||
res.push(this.preloadConfig(ngModule, c));
|
res.push(this.preloadConfig(ngModule, route));
|
||||||
|
|
||||||
// recurse into children
|
// recurse into children
|
||||||
} else if (c.children) {
|
} else if (route.children) {
|
||||||
res.push(this.processRoutes(ngModule, c.children));
|
res.push(this.processRoutes(ngModule, route.children));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return mergeAll.call(from(res));
|
return mergeAll.call(from(res));
|
||||||
}
|
}
|
||||||
|
|
||||||
private preloadConfig(ngModule: NgModuleRef<any>, route: Route): Observable<void> {
|
private preloadConfig(ngModule: NgModuleRef<any>, route: InternalRoute): Observable<void> {
|
||||||
return this.preloadingStrategy.preload(route, () => {
|
return this.preloadingStrategy.preload(route, () => {
|
||||||
const loaded = this.loader.load(ngModule.injector, route);
|
const loaded = this.loader.load(ngModule.injector, route);
|
||||||
return mergeMap.call(loaded, (config: any): any => {
|
return mergeMap.call(loaded, (config: any): any => {
|
||||||
const c: any = route;
|
route._loadedConfig = config;
|
||||||
c._loadedConfig = config;
|
|
||||||
return this.processRoutes(config.module, config.routes);
|
return this.processRoutes(config.module, config.routes);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -345,7 +345,7 @@ export function serializePath(path: UrlSegment): string {
|
||||||
}
|
}
|
||||||
|
|
||||||
function serializeParams(params: {[key: string]: string}): string {
|
function serializeParams(params: {[key: string]: string}): string {
|
||||||
return pairs(params).map(p => `;${encode(p.first)}=${encode(p.second)}`).join('');
|
return Object.keys(params).map(key => `;${encode(key)}=${encode(params[key])}`).join('');
|
||||||
}
|
}
|
||||||
|
|
||||||
function serializeQueryParams(params: {[key: string]: any}): string {
|
function serializeQueryParams(params: {[key: string]: any}): string {
|
||||||
|
@ -358,20 +358,6 @@ function serializeQueryParams(params: {[key: string]: any}): string {
|
||||||
return strParams.length ? `?${strParams.join("&")}` : '';
|
return strParams.length ? `?${strParams.join("&")}` : '';
|
||||||
}
|
}
|
||||||
|
|
||||||
class Pair<A, B> {
|
|
||||||
constructor(public first: A, public second: B) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
function pairs<T>(obj: {[key: string]: T}): Pair<string, T>[] {
|
|
||||||
const res: Pair<string, T>[] = [];
|
|
||||||
for (const prop in obj) {
|
|
||||||
if (obj.hasOwnProperty(prop)) {
|
|
||||||
res.push(new Pair<string, T>(prop, obj[prop]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
const SEGMENT_RE = /^[^\/()?;=&#]+/;
|
const SEGMENT_RE = /^[^\/()?;=&#]+/;
|
||||||
function matchSegments(str: string): string {
|
function matchSegments(str: string): string {
|
||||||
SEGMENT_RE.lastIndex = 0;
|
SEGMENT_RE.lastIndex = 0;
|
||||||
|
|
Loading…
Reference in New Issue