fix: element injector vs module injector (#15044)
fixes #12869 fixes #12889 fixes #13885 fixes #13870 Before this change there was a single injector tree. Now we have 2 injector trees, one for the modules and one for the components. This fixes lazy loading modules. See the design docs for details: https://docs.google.com/document/d/1OEUIwc-s69l1o97K0wBd_-Lth5BBxir1KuCRWklTlI4 BREAKING CHANGES `ComponentFactory.create()` takes an extra optional `NgModuleRef` parameter. No change should be required in user code as the correct module will be used when none is provided DEPRECATIONS The following methods were used internally and are no more required: - `RouterOutlet.locationFactoryResolver` - `RouterOutlet.locationInjector`
This commit is contained in:

committed by
Chuck Jazdzewski

parent
f093501501
commit
13686bb518
@ -6,7 +6,7 @@
|
||||
*found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {Compiler, Injectable, Injector, NgModuleFactoryLoader} from '@angular/core';
|
||||
import {Compiler, Injectable, Injector, NgModuleFactoryLoader, NgModuleRef} from '@angular/core';
|
||||
import {Observable} from 'rxjs/Observable';
|
||||
import {Subscription} from 'rxjs/Subscription';
|
||||
import {from} from 'rxjs/observable/from';
|
||||
@ -91,37 +91,40 @@ export class RouterPreloader {
|
||||
this.subscription = concatMap.call(navigations, () => this.preload()).subscribe(() => {});
|
||||
}
|
||||
|
||||
preload(): Observable<any> { return this.processRoutes(this.injector, this.router.config); }
|
||||
preload(): Observable<any> {
|
||||
const ngModule = this.injector.get(NgModuleRef);
|
||||
return this.processRoutes(ngModule, this.router.config);
|
||||
}
|
||||
|
||||
ngOnDestroy(): void { this.subscription.unsubscribe(); }
|
||||
|
||||
private processRoutes(injector: Injector, routes: Routes): Observable<void> {
|
||||
private processRoutes(ngModule: NgModuleRef<any>, routes: Routes): Observable<void> {
|
||||
const res: Observable<any>[] = [];
|
||||
for (const c of routes) {
|
||||
// we already have the config loaded, just recurse
|
||||
if (c.loadChildren && !c.canLoad && (<any>c)._loadedConfig) {
|
||||
const childConfig = (<any>c)._loadedConfig;
|
||||
res.push(this.processRoutes(childConfig.injector, childConfig.routes));
|
||||
res.push(this.processRoutes(childConfig.module, childConfig.routes));
|
||||
|
||||
// no config loaded, fetch the config
|
||||
} else if (c.loadChildren && !c.canLoad) {
|
||||
res.push(this.preloadConfig(injector, c));
|
||||
res.push(this.preloadConfig(ngModule, c));
|
||||
|
||||
// recurse into children
|
||||
} else if (c.children) {
|
||||
res.push(this.processRoutes(injector, c.children));
|
||||
res.push(this.processRoutes(ngModule, c.children));
|
||||
}
|
||||
}
|
||||
return mergeAll.call(from(res));
|
||||
}
|
||||
|
||||
private preloadConfig(injector: Injector, route: Route): Observable<void> {
|
||||
private preloadConfig(ngModule: NgModuleRef<any>, route: Route): Observable<void> {
|
||||
return this.preloadingStrategy.preload(route, () => {
|
||||
const loaded = this.loader.load(injector, route);
|
||||
const loaded = this.loader.load(ngModule.injector, route);
|
||||
return mergeMap.call(loaded, (config: any): any => {
|
||||
const c: any = route;
|
||||
c._loadedConfig = config;
|
||||
return this.processRoutes(config.injector, config.routes);
|
||||
return this.processRoutes(config.module, config.routes);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
Reference in New Issue
Block a user