@@ -175,18 +175,22 @@ export class IonRouterOutlet implements OnDestroy, OnInit {
175
175
176
176
const factory = resolver . resolveComponentFactory ( component ) ;
177
177
const childContexts = this . parentContexts . getOrCreateContext ( this . name ) . children ;
178
- const activatedRouteProxy = this . createActivatedRouteProxy ( activatedRoute ) ;
178
+
179
+ // We create an activated route proxy object that will maintain future updates for this component
180
+ // over its lifecycle in the stack.
181
+ const component$ = new BehaviorSubject < any > ( null ) ;
182
+ const activatedRouteProxy = this . createActivatedRouteProxy ( component$ , activatedRoute ) ;
179
183
180
184
const injector = new OutletInjector ( activatedRouteProxy , childContexts , this . location . injector ) ;
181
185
cmpRef = this . activated = this . location . createComponent ( factory , this . location . length , injector ) ;
182
186
187
+ // Once the component is created we can push it to our local subject supplied to the proxy
188
+ component$ . next ( cmpRef . instance ) ;
189
+
183
190
// Calling `markForCheck` to make sure we will run the change detection when the
184
191
// `RouterOutlet` is inside a `ChangeDetectionStrategy.OnPush` component.
185
192
enteringView = this . stackCtrl . createView ( this . activated , activatedRoute ) ;
186
193
187
- // Once the component is created, use the component instance to setup observables
188
- this . setupProxyObservables ( activatedRouteProxy , cmpRef . instance ) ;
189
-
190
194
// Store references to the proxy by component
191
195
this . proxyMap . set ( cmpRef . instance , activatedRouteProxy ) ;
192
196
this . currentActivatedRoute$ . next ( { component : cmpRef . instance , activatedRoute } ) ;
@@ -232,43 +236,49 @@ export class IonRouterOutlet implements OnDestroy, OnInit {
232
236
}
233
237
234
238
/**
235
- * Creates a proxy object that we can use to update activated route properties without losing reference
236
- * in the component injector
239
+ * Since the activated route can change over the life time of a component in an ion router outlet, we create
240
+ * a proxy so that we can update the values over time as a user navigates back to components already in the stack.
237
241
*/
238
- private createActivatedRouteProxy ( activatedRoute : ActivatedRoute ) : ActivatedRoute {
242
+ private createActivatedRouteProxy ( component$ : Observable < any > , activatedRoute : ActivatedRoute ) : ActivatedRoute {
239
243
const proxy : any = new ActivatedRoute ( ) ;
244
+
240
245
proxy . _futureSnapshot = ( activatedRoute as any ) . _futureSnapshot ;
241
246
proxy . _routerState = ( activatedRoute as any ) . _routerState ;
242
247
proxy . snapshot = activatedRoute . snapshot ;
243
248
proxy . outlet = activatedRoute . outlet ;
244
249
proxy . component = activatedRoute . component ;
245
250
246
- return proxy as ActivatedRoute ;
247
- }
251
+ // Setup wrappers for the observables so consumers don't have to worry about switching to new observables as the state updates
252
+ ( proxy as any ) . _paramMap = this . proxyObservable ( component$ , 'paramMap' ) ;
253
+ ( proxy as any ) . _queryParamMap = this . proxyObservable ( component$ , 'queryParamMap' ) ;
254
+ proxy . url = this . proxyObservable ( component$ , 'url' ) ;
255
+ proxy . params = this . proxyObservable ( component$ , 'params' ) ;
256
+ proxy . queryParams = this . proxyObservable ( component$ , 'queryParams' ) ;
257
+ proxy . fragment = this . proxyObservable ( component$ , 'fragment' ) ;
258
+ proxy . data = this . proxyObservable ( component$ , 'data' ) ;
248
259
249
- private setupProxyObservables ( proxy : ActivatedRoute , component : any ) : void {
250
- ( proxy as any ) . _paramMap = this . proxyObservable ( component , 'paramMap' ) ;
251
- ( proxy as any ) . _queryParamMap = this . proxyObservable ( component , 'queryParamMap' ) ;
252
- proxy . url = this . proxyObservable ( component , 'url' ) ;
253
- proxy . params = this . proxyObservable ( component , 'params' ) ;
254
- proxy . queryParams = this . proxyObservable ( component , 'queryParams' ) ;
255
- proxy . fragment = this . proxyObservable ( component , 'fragment' ) ;
256
- proxy . data = this . proxyObservable ( component , 'data' ) ;
260
+ return proxy as ActivatedRoute ;
257
261
}
258
262
259
263
/**
260
- * Create a wrapped observable that will switch to the latest activated route matched by the given view id
264
+ * Create a wrapped observable that will switch to the latest activated route matched by the given component
261
265
*/
262
- private proxyObservable ( component : any , path : string ) : Observable < any > {
263
- return this . currentActivatedRoute$ . pipe (
264
- filter ( current => current !== null && current . component === component ) ,
265
- switchMap ( current => current && ( current . activatedRoute as any ) [ path ] ) ,
266
- distinctUntilChanged ( )
266
+ private proxyObservable ( component$ : Observable < any > , path : string ) : Observable < any > {
267
+ return component$ . pipe (
268
+ // First wait until the component instance is pushed
269
+ filter ( component => ! ! component ) ,
270
+ switchMap ( component =>
271
+ this . currentActivatedRoute$ . pipe (
272
+ filter ( current => current !== null && current . component === component ) ,
273
+ switchMap ( current => current && ( current . activatedRoute as any ) [ path ] ) ,
274
+ distinctUntilChanged ( )
275
+ )
276
+ )
267
277
) ;
268
278
}
269
279
270
280
/**
271
- * Updates the given proxy route with data from the new incoming route
281
+ * Updates the activated route proxy for the given component to the new incoming router state
272
282
*/
273
283
private updateActivatedRouteProxy ( component : any , activatedRoute : ActivatedRoute ) : void {
274
284
const proxy = this . proxyMap . get ( component ) ;
0 commit comments