/** * @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 {Compiler, InjectionToken, Injector, NgModuleFactory, NgModuleFactoryLoader} from '@angular/core'; import {from, Observable, of} from 'rxjs'; import {map, mergeMap} from 'rxjs/operators'; import {LoadChildren, LoadedRouterConfig, Route} from './config'; import {flatten, wrapIntoObservable} from './utils/collection'; import {standardizeConfig} from './utils/config'; /** * The [DI token](guide/glossary/#di-token) for a router configuration. * @see `ROUTES` * @publicApi */ export const ROUTES = new InjectionToken('ROUTES'); export class RouterConfigLoader { constructor( private loader: NgModuleFactoryLoader, private compiler: Compiler, private onLoadStartListener?: (r: Route) => void, private onLoadEndListener?: (r: Route) => void) {} load(parentInjector: Injector, route: Route): Observable { if (this.onLoadStartListener) { this.onLoadStartListener(route); } const moduleFactory$ = this.loadModuleFactory(route.loadChildren!); return moduleFactory$.pipe(map((factory: NgModuleFactory) => { if (this.onLoadEndListener) { this.onLoadEndListener(route); } const module = factory.create(parentInjector); return new LoadedRouterConfig( flatten(module.injector.get(ROUTES)).map(standardizeConfig), module); })); } private loadModuleFactory(loadChildren: LoadChildren): Observable> { if (typeof loadChildren === 'string') { return from(this.loader.load(loadChildren)); } else { return wrapIntoObservable(loadChildren()).pipe(mergeMap((t: any) => { if (t instanceof NgModuleFactory) { return of(t); } else { return from(this.compiler.compileModuleAsync(t)); } })); } } }