1
1
/** @module ng2 */ /** */
2
- import { NgModuleFactoryLoader , NgModuleRef , Injector , NgModuleFactory } from "@angular/core" ;
2
+ import { NgModuleFactoryLoader , NgModuleRef , Injector , NgModuleFactory , Type , Compiler } from "@angular/core" ;
3
3
4
4
import { LazyLoadResult } from "../state/interface" ;
5
5
@@ -10,6 +10,8 @@ import {UIRouter} from "../router";
10
10
import { Resolvable } from "../resolve/resolvable" ;
11
11
import { NATIVE_INJECTOR_TOKEN } from "../resolve/resolveContext" ;
12
12
13
+ export type ModuleTypeCallback = ( ) => Type < any > | Promise < Type < any > > ;
14
+
13
15
/**
14
16
* Returns a function which lazy loads a nested module
15
17
*
@@ -24,23 +26,47 @@ import {NATIVE_INJECTOR_TOKEN} from "../resolve/resolveContext";
24
26
*
25
27
* returns the new states array
26
28
*/
27
- export function loadNgModule ( path : string ) : ( transition : Transition ) => Promise < LazyLoadResult > {
29
+ export function loadNgModule ( moduleToLoad : string | ModuleTypeCallback ) : ( transition : Transition ) => Promise < LazyLoadResult > {
28
30
/** Get the parent NgModule Injector (from resolves) */
29
31
const getNg2Injector = ( transition : Transition ) =>
30
32
transition . injector ( ) . getAsync ( NATIVE_INJECTOR_TOKEN ) ;
31
33
34
+ /**
35
+ * Returns the module factory that can be used to instantiate a module
36
+ *
37
+ * For strings this:
38
+ * - Finds the correct NgModuleFactoryLoader
39
+ * - Loads the new NgModuleFactory from the path string (async)
40
+ *
41
+ * For a Type<any> or Promise<Type<any>> this:
42
+ * - Compiles the component type (if not running with AOT)
43
+ * - Returns the NgModuleFactory resulting from compilation (or direct loading if using AOT) as a Promise
44
+ *
45
+ */
46
+ const loadModuleFactory = ( loadChildren : string | ModuleTypeCallback , ng2Injector : Injector ) : Promise < NgModuleFactory < any > > => {
47
+ if ( typeof ( loadChildren ) === 'string' ) {
48
+ return ng2Injector . get ( NgModuleFactoryLoader ) . load ( loadChildren ) ;
49
+ }
50
+ else {
51
+ const compiler : Compiler = ng2Injector . get ( Compiler ) ;
52
+ const offlineMode = compiler instanceof Compiler ;
53
+ const loadChildrenPromise = Promise . resolve ( loadChildren ( ) ) ;
54
+ return offlineMode ? loadChildrenPromise : loadChildrenPromise . then ( moduleType => compiler . compileModuleAsync ( moduleType ) )
55
+ }
56
+ }
57
+
32
58
/**
33
59
* Lazy loads the NgModule using the NgModuleFactoryLoader
34
60
*
35
61
* Use the parent NgModule's Injector to:
36
- * - Find the correct NgModuleFactoryLoader
37
- * - Load the new NgModuleFactory from the path string (async)
62
+ * - Find the correct NgModuleFactory
38
63
* - Create the new NgModule
39
64
*/
40
- const createNg2Module = ( path : string , ng2Injector : Injector ) =>
41
- ng2Injector . get ( NgModuleFactoryLoader ) . load ( path ) . then ( ( factory : NgModuleFactory < any > ) =>
65
+ const createNg2Module = ( moduleToLoad : string | ModuleTypeCallback , ng2Injector : Injector ) =>
66
+ loadModuleFactory ( moduleToLoad , ng2Injector ) . then ( ( factory : NgModuleFactory < any > ) =>
42
67
factory . create ( ng2Injector ) ) ;
43
68
69
+
44
70
/**
45
71
* Apply the UI-Router Modules found in the lazy loaded module.
46
72
*
@@ -75,7 +101,7 @@ export function loadNgModule(path: string): (transition: Transition) => Promise<
75
101
76
102
let replacementState = uiRouter . stateRegistry . get ( originalName ) ;
77
103
if ( replacementState === originalState ) {
78
- throw new Error ( `The module that was loaded from ${ path } should have a ui-router state named '${ originalName } '` ) ;
104
+ throw new Error ( `The module that was loaded from ${ moduleToLoad } should have a ui-router state named '${ originalName } '` ) ;
79
105
}
80
106
81
107
// Supply the newly loaded states with the Injector from the lazy loaded NgModule
@@ -85,6 +111,6 @@ export function loadNgModule(path: string): (transition: Transition) => Promise<
85
111
}
86
112
87
113
return ( transition : Transition ) => getNg2Injector ( transition )
88
- . then ( ( injector : Injector ) => createNg2Module ( path , injector ) )
114
+ . then ( ( injector : Injector ) => createNg2Module ( moduleToLoad , injector ) )
89
115
. then ( ( moduleRef : NgModuleRef < any > ) => loadUIRouterModules ( transition , moduleRef ) )
90
116
}
0 commit comments