feat(router): support sibling modules providing routes
This commit is contained in:
parent
8efbcc996a
commit
29caa37943
|
@ -9,12 +9,13 @@
|
||||||
import {Location, LocationStrategy, PathLocationStrategy} from '@angular/common';
|
import {Location, LocationStrategy, PathLocationStrategy} from '@angular/common';
|
||||||
import {ANALYZE_FOR_ENTRY_COMPONENTS, APP_BOOTSTRAP_LISTENER, APP_INITIALIZER, ApplicationRef, ComponentResolver, Injector, NgModuleFactoryLoader, OpaqueToken, SystemJsNgModuleLoader} from '@angular/core';
|
import {ANALYZE_FOR_ENTRY_COMPONENTS, APP_BOOTSTRAP_LISTENER, APP_INITIALIZER, ApplicationRef, ComponentResolver, Injector, NgModuleFactoryLoader, OpaqueToken, SystemJsNgModuleLoader} from '@angular/core';
|
||||||
|
|
||||||
import {Routes} from './config';
|
import {Route, Routes} from './config';
|
||||||
import {Router} from './router';
|
import {Router} from './router';
|
||||||
import {ROUTER_CONFIG, ROUTES} from './router_config_loader';
|
import {ROUTER_CONFIG, ROUTES} from './router_config_loader';
|
||||||
import {RouterOutletMap} from './router_outlet_map';
|
import {RouterOutletMap} from './router_outlet_map';
|
||||||
import {ActivatedRoute} from './router_state';
|
import {ActivatedRoute} from './router_state';
|
||||||
import {DefaultUrlSerializer, UrlSerializer} from './url_tree';
|
import {DefaultUrlSerializer, UrlSerializer} from './url_tree';
|
||||||
|
import {flatten} from './utils/collection';
|
||||||
|
|
||||||
export const ROUTER_CONFIGURATION = new OpaqueToken('ROUTER_CONFIGURATION');
|
export const ROUTER_CONFIGURATION = new OpaqueToken('ROUTER_CONFIGURATION');
|
||||||
|
|
||||||
|
@ -29,13 +30,14 @@ export interface ExtraOptions {
|
||||||
export function setupRouter(
|
export function setupRouter(
|
||||||
ref: ApplicationRef, resolver: ComponentResolver, urlSerializer: UrlSerializer,
|
ref: ApplicationRef, resolver: ComponentResolver, urlSerializer: UrlSerializer,
|
||||||
outletMap: RouterOutletMap, location: Location, injector: Injector,
|
outletMap: RouterOutletMap, location: Location, injector: Injector,
|
||||||
loader: NgModuleFactoryLoader, config: Routes, opts: ExtraOptions = {}) {
|
loader: NgModuleFactoryLoader, config: Route[][], opts: ExtraOptions = {}) {
|
||||||
if (ref.componentTypes.length == 0) {
|
if (ref.componentTypes.length == 0) {
|
||||||
throw new Error('Bootstrap at least one component before injecting Router.');
|
throw new Error('Bootstrap at least one component before injecting Router.');
|
||||||
}
|
}
|
||||||
const componentType = ref.componentTypes[0];
|
const componentType = ref.componentTypes[0];
|
||||||
const r = new Router(
|
const r = new Router(
|
||||||
componentType, resolver, urlSerializer, outletMap, location, injector, loader, config);
|
componentType, resolver, urlSerializer, outletMap, location, injector, loader,
|
||||||
|
flatten(config));
|
||||||
|
|
||||||
if (opts.enableTracing) {
|
if (opts.enableTracing) {
|
||||||
r.events.subscribe(e => {
|
r.events.subscribe(e => {
|
||||||
|
@ -130,7 +132,7 @@ export function provideRouterInitializer() {
|
||||||
export function provideRoutes(routes: Routes): any {
|
export function provideRoutes(routes: Routes): any {
|
||||||
return [
|
return [
|
||||||
{provide: ANALYZE_FOR_ENTRY_COMPONENTS, multi: true, useValue: routes},
|
{provide: ANALYZE_FOR_ENTRY_COMPONENTS, multi: true, useValue: routes},
|
||||||
{provide: ROUTES, useValue: routes}
|
{provide: ROUTES, multi: true, useValue: routes}
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ import {Observable} from 'rxjs/Observable';
|
||||||
import {fromPromise} from 'rxjs/observable/fromPromise';
|
import {fromPromise} from 'rxjs/observable/fromPromise';
|
||||||
|
|
||||||
import {Route} from './config';
|
import {Route} from './config';
|
||||||
|
import {flatten} from './utils/collection';
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -33,7 +33,7 @@ export class RouterConfigLoader {
|
||||||
return fromPromise(this.loader.load(path).then(r => {
|
return fromPromise(this.loader.load(path).then(r => {
|
||||||
const ref = r.create(parentInjector);
|
const ref = r.create(parentInjector);
|
||||||
return new LoadedRouterConfig(
|
return new LoadedRouterConfig(
|
||||||
ref.injector.get(ROUTES), ref.injector, ref.componentFactoryResolver);
|
flatten(ref.injector.get(ROUTES)), ref.injector, ref.componentFactoryResolver);
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1445,6 +1445,57 @@ describe('Integration', () => {
|
||||||
.toHaveText('lazy-loaded-parent [lazy-loaded-child]');
|
.toHaveText('lazy-loaded-parent [lazy-loaded-child]');
|
||||||
})));
|
})));
|
||||||
|
|
||||||
|
it('should combine routes from multiple modules into a single configuration',
|
||||||
|
fakeAsync(inject(
|
||||||
|
[Router, TestComponentBuilder, Location, NgModuleFactoryLoader],
|
||||||
|
(router: Router, tcb: TestComponentBuilder, location: Location,
|
||||||
|
loader: SpyNgModuleFactoryLoader) => {
|
||||||
|
@Component({selector: 'lazy', template: 'lazy-loaded-2'})
|
||||||
|
class LazyComponent2 {
|
||||||
|
}
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
declarations: [LazyComponent2],
|
||||||
|
imports: [RouterModule.forChild([{path: 'loaded', component: LazyComponent2}])],
|
||||||
|
entryComponents: [LazyComponent2]
|
||||||
|
})
|
||||||
|
class SiblingOfLoadedModule {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Component(
|
||||||
|
{selector: 'lazy', template: 'lazy-loaded-1', directives: ROUTER_DIRECTIVES})
|
||||||
|
class LazyComponent1 {
|
||||||
|
}
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
declarations: [LazyComponent1],
|
||||||
|
imports: [
|
||||||
|
RouterModule.forChild([{path: 'loaded', component: LazyComponent1}]),
|
||||||
|
SiblingOfLoadedModule
|
||||||
|
],
|
||||||
|
entryComponents: [LazyComponent1]
|
||||||
|
})
|
||||||
|
class LoadedModule {
|
||||||
|
}
|
||||||
|
|
||||||
|
loader.stubbedModules = {expected1: LoadedModule, expected2: SiblingOfLoadedModule};
|
||||||
|
|
||||||
|
const fixture = createRoot(tcb, router, RootCmp);
|
||||||
|
|
||||||
|
router.resetConfig([
|
||||||
|
{path: 'lazy1', loadChildren: 'expected1'},
|
||||||
|
{path: 'lazy2', loadChildren: 'expected2'}
|
||||||
|
]);
|
||||||
|
|
||||||
|
router.navigateByUrl('/lazy1/loaded');
|
||||||
|
advance(fixture);
|
||||||
|
expect(location.path()).toEqual('/lazy1/loaded');
|
||||||
|
|
||||||
|
router.navigateByUrl('/lazy2/loaded');
|
||||||
|
advance(fixture);
|
||||||
|
expect(location.path()).toEqual('/lazy2/loaded');
|
||||||
|
})));
|
||||||
|
|
||||||
it('should use the injector of the lazily-loaded configuration',
|
it('should use the injector of the lazily-loaded configuration',
|
||||||
fakeAsync(inject(
|
fakeAsync(inject(
|
||||||
[Router, TestComponentBuilder, Location, NgModuleFactoryLoader],
|
[Router, TestComponentBuilder, Location, NgModuleFactoryLoader],
|
||||||
|
|
|
@ -10,9 +10,10 @@ import {Location, LocationStrategy} from '@angular/common';
|
||||||
import {MockLocationStrategy, SpyLocation} from '@angular/common/testing';
|
import {MockLocationStrategy, SpyLocation} from '@angular/common/testing';
|
||||||
import {Compiler, ComponentResolver, Injectable, Injector, NgModule, NgModuleFactory, NgModuleFactoryLoader} from '@angular/core';
|
import {Compiler, ComponentResolver, Injectable, Injector, NgModule, NgModuleFactory, NgModuleFactoryLoader} from '@angular/core';
|
||||||
|
|
||||||
import {Router, RouterOutletMap, Routes, UrlSerializer} from '../index';
|
import {Route, Router, RouterOutletMap, UrlSerializer} from '../index';
|
||||||
import {ROUTES} from '../src/router_config_loader';
|
import {ROUTES} from '../src/router_config_loader';
|
||||||
import {ROUTER_PROVIDERS, RouterModule} from '../src/router_module';
|
import {ROUTER_PROVIDERS, RouterModule} from '../src/router_module';
|
||||||
|
import {flatten} from '../src/utils/collection';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -39,8 +40,9 @@ export class SpyNgModuleFactoryLoader implements NgModuleFactoryLoader {
|
||||||
|
|
||||||
function setupTestingRouter(
|
function setupTestingRouter(
|
||||||
resolver: ComponentResolver, urlSerializer: UrlSerializer, outletMap: RouterOutletMap,
|
resolver: ComponentResolver, urlSerializer: UrlSerializer, outletMap: RouterOutletMap,
|
||||||
location: Location, loader: NgModuleFactoryLoader, injector: Injector, routes: Routes) {
|
location: Location, loader: NgModuleFactoryLoader, injector: Injector, routes: Route[][]) {
|
||||||
return new Router(null, resolver, urlSerializer, outletMap, location, injector, loader, routes);
|
return new Router(
|
||||||
|
null, resolver, urlSerializer, outletMap, location, injector, loader, flatten(routes));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue