@@ -87,40 +87,25 @@ const ng2ComponentInputs = (factory: ComponentFactory<any>): InputMapping[] => {
87
87
*/
88
88
@Component ( {
89
89
selector : 'ui-view, [ui-view]' ,
90
+ exportAs : 'uiView' ,
90
91
template : `
91
92
<ng-template #componentTarget></ng-template>
92
- <ng-content *ngIf="!componentRef "></ng-content>
93
+ <ng-content *ngIf="!_componentRef "></ng-content>
93
94
`
94
- // styles: [`
95
- // .done-true {
96
- // text-decoration: line-through;
97
- // color: grey;
98
- // }`
99
- // ],
100
- // template: `
101
- // <div style="padding: 1em; border: 1px solid lightgrey;">
102
- //
103
- // <div #content style="color: lightgrey; font-size: smaller;">
104
- // <div>ui-view #{{uiViewData?.id}} created by '{{ parentContext?.name || "(root)" }}' state</div>
105
- // <div>name: (absolute) '{{uiViewData?.fqn}}' (contextual) '{{uiViewData?.name}}@{{parentContext?.name}}' </div>
106
- // <div>currently filled by: '{{(uiViewData?.config && uiViewData?.config?.viewDecl?.$context) || 'empty...'}}'</div>
107
- // </div>
108
- //
109
- // </div>`
110
95
} )
111
96
export class UIView {
112
- @ViewChild ( 'componentTarget' , { read : ViewContainerRef } ) componentTarget : ViewContainerRef ;
97
+ @ViewChild ( 'componentTarget' , { read : ViewContainerRef } ) _componentTarget : ViewContainerRef ;
113
98
@Input ( 'name' ) name : string ;
114
99
@Input ( 'ui-view' ) set _name ( val : string ) { this . name = val ; }
115
100
/** The reference to the component currently inside the viewport */
116
- componentRef : ComponentRef < any > ;
101
+ _componentRef : ComponentRef < any > ;
117
102
/** Deregisters the ui-view from the view service */
118
- deregisterUIView : Function ;
103
+ private _deregisterUIView : Function ;
119
104
/** Deregisters the master uiCanExit transition hook */
120
- deregisterHook : Function ;
105
+ private _deregisterHook : Function ;
121
106
/** Data about the this UIView */
122
- uiViewData : ActiveUIView = < any > { } ;
123
- parent : ParentUIViewInject ;
107
+ private _uiViewData : ActiveUIView = < any > { } ;
108
+ private _parent : ParentUIViewInject ;
124
109
125
110
static PARENT_INJECT = "UIView.PARENT_INJECT" ;
126
111
@@ -129,26 +114,26 @@ export class UIView {
129
114
@Inject ( UIView . PARENT_INJECT ) parent ,
130
115
public viewContainerRef : ViewContainerRef ,
131
116
) {
132
- this . parent = parent ;
117
+ this . _parent = parent ;
133
118
}
134
119
135
120
ngOnInit ( ) {
136
121
const router = this . router ;
137
- const parentFqn = this . parent . fqn ;
122
+ const parentFqn = this . _parent . fqn ;
138
123
const name = this . name || '$default' ;
139
124
140
- this . uiViewData = {
125
+ this . _uiViewData = {
141
126
$type : 'ng2' ,
142
127
id : id ++ ,
143
128
name : name ,
144
129
fqn : parentFqn ? parentFqn + "." + name : name ,
145
- creationContext : this . parent . context ,
146
- configUpdated : this . viewConfigUpdated . bind ( this ) ,
130
+ creationContext : this . _parent . context ,
131
+ configUpdated : this . _viewConfigUpdated . bind ( this ) ,
147
132
config : undefined
148
133
} ;
149
134
150
- this . deregisterHook = router . transitionService . onBefore ( { } , trans => this . applyUiCanExitHook ( trans ) ) ;
151
- this . deregisterUIView = router . viewService . registerUIView ( this . uiViewData ) ;
135
+ this . _deregisterHook = router . transitionService . onBefore ( { } , trans => this . _applyUiCanExitHook ( trans ) ) ;
136
+ this . _deregisterUIView = router . viewService . registerUIView ( this . _uiViewData ) ;
152
137
}
153
138
154
139
/**
@@ -159,12 +144,12 @@ export class UIView {
159
144
*
160
145
* If both are true, adds the uiCanExit component function as a hook to that singular Transition.
161
146
*/
162
- applyUiCanExitHook ( trans : Transition ) {
163
- const instance = this . componentRef && this . componentRef . instance ;
147
+ private _applyUiCanExitHook ( trans : Transition ) {
148
+ const instance = this . _componentRef && this . _componentRef . instance ;
164
149
const uiCanExitFn : TransitionHookFn = instance && instance . uiCanExit ;
165
150
166
151
if ( isFunction ( uiCanExitFn ) ) {
167
- const state : StateDeclaration = parse ( "uiViewData .config.viewDecl.$context.self" ) ( this ) ;
152
+ const state : StateDeclaration = parse ( "_uiViewData .config.viewDecl.$context.self" ) ( this ) ;
168
153
169
154
if ( trans . exiting ( ) . indexOf ( state ) !== - 1 ) {
170
155
trans . onStart ( { } , function ( ) {
@@ -174,55 +159,58 @@ export class UIView {
174
159
}
175
160
}
176
161
177
- disposeLast ( ) {
178
- if ( this . componentRef ) this . componentRef . destroy ( ) ;
179
- this . componentRef = null ;
162
+ private _disposeLast ( ) {
163
+ if ( this . _componentRef ) this . _componentRef . destroy ( ) ;
164
+ this . _componentRef = null ;
180
165
}
181
166
182
167
ngOnDestroy ( ) {
183
- if ( this . deregisterUIView ) this . deregisterUIView ( ) ;
184
- if ( this . deregisterHook ) this . deregisterHook ( ) ;
185
- this . disposeLast ( ) ;
168
+ if ( this . _deregisterUIView ) this . _deregisterUIView ( ) ;
169
+ if ( this . _deregisterHook ) this . _deregisterHook ( ) ;
170
+ this . _disposeLast ( ) ;
186
171
}
187
172
188
173
/**
189
174
* The view service is informing us of an updated ViewConfig
190
175
* (usually because a transition activated some state and its views)
191
176
*/
192
- viewConfigUpdated ( config : ViewConfig ) {
177
+ _viewConfigUpdated ( config : ViewConfig ) {
193
178
// The config may be undefined if there is nothing currently targeting this UIView.
194
179
// Dispose the current component, if there is one
195
- if ( ! config ) return this . disposeLast ( ) ;
180
+ if ( ! config ) return this . _disposeLast ( ) ;
196
181
197
182
// Only care about Ng2 configs
198
183
if ( ! ( config instanceof Ng2ViewConfig ) ) return ;
199
184
200
185
// The "new" viewconfig is already applied, so exit early
201
- if ( this . uiViewData . config === config ) return ;
186
+ if ( this . _uiViewData . config === config ) return ;
202
187
203
188
// This is a new ViewConfig. Dispose the previous component
204
- this . disposeLast ( ) ;
205
- trace . traceUIViewConfigUpdated ( this . uiViewData , config && config . viewDecl . $context ) ;
189
+ this . _disposeLast ( ) ;
190
+ trace . traceUIViewConfigUpdated ( this . _uiViewData , config && config . viewDecl . $context ) ;
206
191
207
- this . applyUpdatedConfig ( config ) ;
192
+ this . _applyUpdatedConfig ( config ) ;
208
193
}
209
194
210
- applyUpdatedConfig ( config : Ng2ViewConfig ) {
211
- this . uiViewData . config = config ;
195
+ private _applyUpdatedConfig ( config : Ng2ViewConfig ) {
196
+ this . _uiViewData . config = config ;
212
197
// Create the Injector for the routed component
213
198
let context = new ResolveContext ( config . path ) ;
214
- let componentInjector = this . getComponentInjector ( context ) ;
199
+ let componentInjector = this . _getComponentInjector ( context ) ;
215
200
216
201
// Get the component class from the view declaration. TODO: allow promises?
217
202
let componentClass = config . viewDecl . component ;
218
203
219
204
// Create the component
220
205
let compFactoryResolver = componentInjector . get ( ComponentFactoryResolver ) ;
221
206
let compFactory = compFactoryResolver . resolveComponentFactory ( componentClass ) ;
222
- this . componentRef = this . componentTarget . createComponent ( compFactory , undefined , componentInjector ) ;
207
+ this . _componentRef = this . _componentTarget . createComponent ( compFactory , undefined , componentInjector ) ;
223
208
224
209
// Wire resolves to @Input ()s
225
- this . applyInputBindings ( compFactory , this . componentRef , context , componentClass ) ;
210
+ this . _applyInputBindings ( compFactory , this . _componentRef . instance , context , componentClass ) ;
211
+
212
+ // Initiate change detection for the newly created component
213
+ this . _componentRef . changeDetectorRef . markForCheck ( ) ;
226
214
}
227
215
228
216
/**
@@ -235,12 +223,12 @@ export class UIView {
235
223
*
236
224
* @returns an Injector
237
225
*/
238
- getComponentInjector ( context : ResolveContext ) : Injector {
226
+ private _getComponentInjector ( context : ResolveContext ) : Injector {
239
227
// Map resolves to "useValue: providers"
240
228
let resolvables = context . getTokens ( ) . map ( token => context . getResolvable ( token ) ) . filter ( r => r . resolved ) ;
241
229
let newProviders = resolvables . map ( r => ( { provide : r . token , useValue : r . data } ) ) ;
242
230
243
- let parentInject = { context : this . uiViewData . config . viewDecl . $context , fqn : this . uiViewData . fqn } ;
231
+ let parentInject = { context : this . _uiViewData . config . viewDecl . $context , fqn : this . _uiViewData . fqn } ;
244
232
newProviders . push ( { provide : UIView . PARENT_INJECT , useValue : parentInject } ) ;
245
233
246
234
let parentComponentInjector = this . viewContainerRef . injector ;
@@ -256,9 +244,8 @@ export class UIView {
256
244
* Finds component inputs which match resolves (by name) and sets the input value
257
245
* to the resolve data.
258
246
*/
259
- applyInputBindings ( factory : ComponentFactory < any > , ref : ComponentRef < any > , context : ResolveContext , componentClass ) {
260
- const component = ref . instance ;
261
- const bindings = this . uiViewData . config . viewDecl [ 'bindings' ] || { } ;
247
+ private _applyInputBindings ( factory : ComponentFactory < any > , component : any , context : ResolveContext , componentClass ) {
248
+ const bindings = this . _uiViewData . config . viewDecl [ 'bindings' ] || { } ;
262
249
const explicitBoundProps = Object . keys ( bindings ) ;
263
250
264
251
// Returns the actual component property for a renamed an input renamed using `@Input('foo') _foo`.
@@ -285,8 +272,5 @@ export class UIView {
285
272
. map ( addResolvable )
286
273
. filter ( tuple => tuple . resolvable && tuple . resolvable . resolved )
287
274
. forEach ( tuple => { component [ tuple . prop ] = tuple . resolvable . data ; } ) ;
288
-
289
- // Initiate change detection for the newly created component
290
- ref . changeDetectorRef . detectChanges ( ) ;
291
275
}
292
276
}
0 commit comments