@@ -10,22 +10,49 @@ import {_ViewDeclaration} from "../state/interface";
10
10
11
11
export type ViewConfigFactory = ( path : PathNode [ ] , decl : _ViewDeclaration ) => ViewConfig | ViewConfig [ ] ;
12
12
13
+ export interface ViewServicePluginAPI {
14
+ _rootViewContext ( context ?: ViewContext ) : ViewContext ;
15
+ _viewConfigFactory ( viewType : string , factory : ViewConfigFactory ) ;
16
+ _registeredUIViews ( ) : ActiveUIView [ ] ;
17
+ _activeViewConfigs ( ) : ViewConfig [ ] ;
18
+ }
19
+
13
20
/**
14
21
* The View service
22
+ *
23
+ * This service pairs existing `ui-view` components (which live in the DOM)
24
+ * with view configs (from the state declaration objects: [[StateDeclaration.views]]).
25
+ *
26
+ * - After a successful Transition, the views from the newly entered states are activated via [[activateViewConfig]].
27
+ * The views from exited states are deactivated via [[deactivateViewConfig]].
28
+ * (See: the [[registerActivateViews]] Transition Hook)
29
+ *
30
+ * - As `ui-view` components pop in and out of existence, they register themselves using [[registerUIView]].
31
+ *
32
+ * - When the [[sync]] function is called, the registered `ui-view`(s) ([[UIViewConfig]]
33
+ * are configured with the matching `ViewConfig`(s) ([[ActiveUIView]]).
34
+ *
15
35
*/
16
36
export class ViewService {
17
- private uiViews : ActiveUIView [ ] = [ ] ;
18
- private viewConfigs : ViewConfig [ ] = [ ] ;
37
+ private _uiViews : ActiveUIView [ ] = [ ] ;
38
+ private _viewConfigs : ViewConfig [ ] = [ ] ;
19
39
private _rootContext : ViewContext ;
20
40
private _viewConfigFactories : { [ key : string ] : ViewConfigFactory } = { } ;
21
41
22
42
constructor ( ) { }
23
43
24
- rootContext ( context ?: ViewContext ) : ViewContext {
44
+ public _pluginapi : ViewServicePluginAPI = {
45
+ _rootViewContext : this . _rootViewContext . bind ( this ) ,
46
+ _viewConfigFactory : this . _viewConfigFactory . bind ( this ) ,
47
+ _registeredUIViews : ( ) => this . _uiViews ,
48
+ _activeViewConfigs : ( ) => this . _viewConfigs ,
49
+ } ;
50
+
51
+ private _rootViewContext ( context ?: ViewContext ) : ViewContext {
25
52
return this . _rootContext = context || this . _rootContext ;
26
53
} ;
27
54
28
- viewConfigFactory ( viewType : string , factory : ViewConfigFactory ) {
55
+ private _viewConfigFactory ( viewType : string , factory : ViewConfigFactory ) {
29
56
this . _viewConfigFactories [ viewType ] = factory ;
30
57
}
31
58
@@ -37,23 +64,26 @@ export class ViewService {
37
64
}
38
65
39
66
/**
40
- * De-registers a ViewConfig.
67
+ * Deactivates a ViewConfig.
68
+ *
69
+ * This function deactivates a `ViewConfig`.
70
+ * After calling [[sync]], it will un-pair from any `ui-view` with which it is currently paired.
41
71
*
42
72
* @param viewConfig The ViewConfig view to deregister.
43
73
*/
44
74
deactivateViewConfig ( viewConfig : ViewConfig ) {
45
75
trace . traceViewServiceEvent ( "<- Removing" , viewConfig ) ;
46
- removeFrom ( this . viewConfigs , viewConfig ) ;
47
- } ;
76
+ removeFrom ( this . _viewConfigs , viewConfig ) ;
77
+ }
48
78
49
79
activateViewConfig ( viewConfig : ViewConfig ) {
50
80
trace . traceViewServiceEvent ( "-> Registering" , < any > viewConfig ) ;
51
- this . viewConfigs . push ( viewConfig ) ;
52
- } ;
81
+ this . _viewConfigs . push ( viewConfig ) ;
82
+ }
53
83
54
- sync = ( ) => {
84
+ sync ( ) {
55
85
let uiViewsByFqn : TypedMap < ActiveUIView > =
56
- this . uiViews . map ( uiv => [ uiv . fqn , uiv ] ) . reduce ( applyPairs , < any > { } ) ;
86
+ this . _uiViews . map ( uiv => [ uiv . fqn , uiv ] ) . reduce ( applyPairs , < any > { } ) ;
57
87
58
88
/**
59
89
* Given a ui-view and a ViewConfig, determines if they "match".
@@ -148,7 +178,7 @@ export class ViewService {
148
178
const depthCompare = curry ( ( depthFn , posNeg , left , right ) => posNeg * ( depthFn ( left ) - depthFn ( right ) ) ) ;
149
179
150
180
const matchingConfigPair = ( uiView : ActiveUIView ) => {
151
- let matchingConfigs = this . viewConfigs . filter ( matches ( uiView ) ) ;
181
+ let matchingConfigs = this . _viewConfigs . filter ( matches ( uiView ) ) ;
152
182
if ( matchingConfigs . length > 1 ) {
153
183
// This is OK. Child states can target a ui-view that the parent state also targets (the child wins)
154
184
// Sort by depth and return the match from the deepest child
@@ -161,25 +191,31 @@ export class ViewService {
161
191
const configureUIView = ( [ uiView , viewConfig ] ) => {
162
192
// If a parent ui-view is reconfigured, it could destroy child ui-views.
163
193
// Before configuring a child ui-view, make sure it's still in the active uiViews array.
164
- if ( this . uiViews . indexOf ( uiView ) !== - 1 )
194
+ if ( this . _uiViews . indexOf ( uiView ) !== - 1 )
165
195
uiView . configUpdated ( viewConfig ) ;
166
196
} ;
167
197
168
- this . uiViews . sort ( depthCompare ( uiViewDepth , 1 ) ) . map ( matchingConfigPair ) . forEach ( configureUIView ) ;
198
+ this . _uiViews . sort ( depthCompare ( uiViewDepth , 1 ) ) . map ( matchingConfigPair ) . forEach ( configureUIView ) ;
169
199
} ;
170
200
171
201
/**
172
- * Allows a `ui-view` element to register its canonical name with a callback that allows it to
173
- * be updated with a template, controller, and local variables.
202
+ * Registers a `ui-view` component
203
+ *
204
+ * When a `ui-view` component is created, it uses this method to register itself.
205
+ * After registration the [[sync]] method is used to ensure all `ui-view` are configured with the proper [[ViewConfig]].
206
+ *
207
+ * Note: the `ui-view` component uses the `ViewConfig` to determine what view should be loaded inside the `ui-view`,
208
+ * and what the view's state context is.
209
+ *
210
+ * Note: There is no corresponding `deregisterUIView`.
211
+ * A `ui-view` should hang on to the return value of `registerUIView` and invoke it to deregister itself.
174
212
*
175
- * @param {String } name The fully-qualified name of the `ui-view` object being registered.
176
- * @param {Function } configUpdatedCallback A callback that receives updates to the content & configuration
177
- * of the view.
178
- * @return {Function } Returns a de-registration function used when the view is destroyed.
213
+ * @param uiView The metadata for a UIView
214
+ * @return a de-registration function used when the view is destroyed.
179
215
*/
180
216
registerUIView ( uiView : ActiveUIView ) {
181
217
trace . traceViewServiceUIViewEvent ( "-> Registering" , uiView ) ;
182
- let uiViews = this . uiViews ;
218
+ let uiViews = this . _uiViews ;
183
219
const fqnMatches = uiv => uiv . fqn === uiView . fqn ;
184
220
if ( uiViews . filter ( fqnMatches ) . length )
185
221
trace . traceViewServiceUIViewEvent ( "!!!! duplicate uiView named:" , uiView ) ;
@@ -204,7 +240,7 @@ export class ViewService {
204
240
* @return {Array } Returns an array of fully-qualified view names.
205
241
*/
206
242
available ( ) {
207
- return this . uiViews . map ( prop ( "fqn" ) ) ;
243
+ return this . _uiViews . map ( prop ( "fqn" ) ) ;
208
244
}
209
245
210
246
/**
@@ -213,7 +249,7 @@ export class ViewService {
213
249
* @return {Array } Returns an array of fully-qualified view names.
214
250
*/
215
251
active ( ) {
216
- return this . uiViews . filter ( prop ( "$config" ) ) . map ( prop ( "name" ) ) ;
252
+ return this . _uiViews . filter ( prop ( "$config" ) ) . map ( prop ( "name" ) ) ;
217
253
}
218
254
219
255
/**
0 commit comments