1
- /** @module resolve */ /** for typedoc */
1
+ /** @module resolve */
2
+ /** for typedoc */
2
3
import { find , tail , uniqR , unnestR , inArray } from "../common/common" ;
3
- import { propEq } from "../common/hof" ;
4
- import { trace } from "../common/trace" ;
5
- import { services , $InjectorLike } from "../common/coreservices" ;
6
- import { resolvePolicies , PolicyWhen } from "./interface" ;
7
-
8
- import { PathNode } from "../path/node" ;
9
- import { Resolvable } from "./resolvable" ;
10
- import { State } from "../state/stateObject" ;
11
- import { PathFactory } from "../path/pathFactory" ;
12
- import { stringify } from "../common/strings" ;
13
- import { Transition } from "../transition/transition" ;
14
- import { UIInjector } from "../interface" ;
4
+ import { propEq , not } from "../common/hof" ;
5
+ import { trace } from "../common/trace" ;
6
+ import { services , $InjectorLike } from "../common/coreservices" ;
7
+ import { resolvePolicies , PolicyWhen , ResolvePolicy } from "./interface" ;
8
+ import { PathNode } from "../path/node" ;
9
+ import { Resolvable } from "./resolvable" ;
10
+ import { State } from "../state/stateObject" ;
11
+ import { PathFactory } from "../path/pathFactory" ;
12
+ import { stringify } from "../common/strings" ;
13
+ import { Transition } from "../transition/transition" ;
14
+ import { UIInjector } from "../interface" ;
15
15
16
16
const when = resolvePolicies . when ;
17
17
const ALL_WHENS = [ when . EAGER , when . LAZY ] ;
@@ -46,12 +46,18 @@ export class ResolveContext {
46
46
* Throws an error if it doesn't exist in the ResolveContext
47
47
*/
48
48
getResolvable ( token : any ) : Resolvable {
49
- var matching = this . _path . map ( node => node . resolvables )
49
+ let matching = this . _path . map ( node => node . resolvables )
50
50
. reduce ( unnestR , [ ] )
51
51
. filter ( ( r : Resolvable ) => r . token === token ) ;
52
52
return tail ( matching ) ;
53
53
}
54
54
55
+ /** Returns the [[ResolvePolicy]] for the given [[Resolvable]] */
56
+ getPolicy ( resolvable : Resolvable ) : ResolvePolicy {
57
+ let node = this . findNode ( resolvable ) ;
58
+ return resolvable . getPolicy ( node . state ) ;
59
+ }
60
+
55
61
/**
56
62
* Returns a ResolveContext that includes a portion of this one
57
63
*
@@ -95,8 +101,8 @@ export class ResolveContext {
95
101
* @param state Used to find the node to put the resolvable on
96
102
*/
97
103
addResolvables ( newResolvables : Resolvable [ ] , state : State ) {
98
- var node = < PathNode > find ( this . _path , propEq ( 'state' , state ) ) ;
99
- var keys = newResolvables . map ( r => r . token ) ;
104
+ let node = < PathNode > find ( this . _path , propEq ( 'state' , state ) ) ;
105
+ let keys = newResolvables . map ( r => r . token ) ;
100
106
node . resolvables = node . resolvables . filter ( r => keys . indexOf ( r . token ) === - 1 ) . concat ( newResolvables ) ;
101
107
}
102
108
@@ -117,19 +123,27 @@ export class ResolveContext {
117
123
// get the subpath to the state argument, if provided
118
124
trace . traceResolvePath ( this . _path , when , trans ) ;
119
125
126
+ const matchesPolicy = ( acceptedVals : string [ ] , whenOrAsync : "when" | "async" ) =>
127
+ ( resolvable : Resolvable ) =>
128
+ inArray ( acceptedVals , this . getPolicy ( resolvable ) [ whenOrAsync ] ) ;
129
+
130
+ // Trigger all the (matching) Resolvables in the path
131
+ // Reduce all the "WAIT" Resolvables into an array
120
132
let promises : Promise < any > [ ] = this . _path . reduce ( ( acc , node ) => {
121
- const matchesRequestedPolicy = ( resolvable : Resolvable ) =>
122
- inArray ( matchedWhens , resolvable . getPolicy ( node . state ) . when ) ;
123
- let nodeResolvables = node . resolvables . filter ( matchesRequestedPolicy ) ;
124
- let subContext = this . subContext ( node . state ) ;
133
+ let nodeResolvables = node . resolvables . filter ( matchesPolicy ( matchedWhens , 'when' ) ) ;
134
+ let nowait = nodeResolvables . filter ( matchesPolicy ( [ 'NOWAIT' ] , 'async' ) ) ;
135
+ let wait = nodeResolvables . filter ( not ( matchesPolicy ( [ 'NOWAIT' ] , 'async' ) ) ) ;
125
136
126
137
// For the matching Resolvables, start their async fetch process.
127
- var getResult = ( r : Resolvable ) => r . get ( subContext , trans )
138
+ let subContext = this . subContext ( node . state ) ;
139
+ let getResult = ( r : Resolvable ) => r . get ( subContext , trans )
128
140
// Return a tuple that includes the Resolvable's token
129
141
. then ( value => ( { token : r . token , value : value } ) ) ;
130
- return acc . concat ( nodeResolvables . map ( getResult ) ) ;
142
+ nowait . forEach ( getResult ) ;
143
+ return acc . concat ( wait . map ( getResult ) ) ;
131
144
} , [ ] ) ;
132
145
146
+ // Wait for all the "WAIT" resolvables
133
147
return services . $q . all ( promises ) ;
134
148
}
135
149
@@ -179,8 +193,12 @@ class UIInjectorImpl implements UIInjector {
179
193
}
180
194
181
195
get ( token : any ) {
182
- var resolvable = this . context . getResolvable ( token ) ;
196
+ let resolvable = this . context . getResolvable ( token ) ;
183
197
if ( resolvable ) {
198
+ if ( this . context . getPolicy ( resolvable ) . async === 'NOWAIT' ) {
199
+ return resolvable . get ( this . context ) ;
200
+ }
201
+
184
202
if ( ! resolvable . resolved ) {
185
203
throw new Error ( "Resolvable async .get() not complete:" + stringify ( resolvable . token ) )
186
204
}
@@ -190,12 +208,12 @@ class UIInjectorImpl implements UIInjector {
190
208
}
191
209
192
210
getAsync ( token : any ) {
193
- var resolvable = this . context . getResolvable ( token ) ;
211
+ let resolvable = this . context . getResolvable ( token ) ;
194
212
if ( resolvable ) return resolvable . get ( this . context ) ;
195
213
return services . $q . when ( this . native . get ( token ) ) ;
196
214
}
197
215
198
216
getNative ( token : any ) {
199
- return this . native . get ( token ) ;
217
+ return this . native && this . native . get ( token ) ;
200
218
}
201
219
}
0 commit comments