@@ -175,18 +175,22 @@ export class IonRouterOutlet implements OnDestroy, OnInit {
175175
176176 const factory = resolver . resolveComponentFactory ( component ) ;
177177 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 ) ;
179183
180184 const injector = new OutletInjector ( activatedRouteProxy , childContexts , this . location . injector ) ;
181185 cmpRef = this . activated = this . location . createComponent ( factory , this . location . length , injector ) ;
182186
187+ // Once the component is created we can push it to our local subject supplied to the proxy
188+ component$ . next ( cmpRef . instance ) ;
189+
183190 // Calling `markForCheck` to make sure we will run the change detection when the
184191 // `RouterOutlet` is inside a `ChangeDetectionStrategy.OnPush` component.
185192 enteringView = this . stackCtrl . createView ( this . activated , activatedRoute ) ;
186193
187- // Once the component is created, use the component instance to setup observables
188- this . setupProxyObservables ( activatedRouteProxy , cmpRef . instance ) ;
189-
190194 // Store references to the proxy by component
191195 this . proxyMap . set ( cmpRef . instance , activatedRouteProxy ) ;
192196 this . currentActivatedRoute$ . next ( { component : cmpRef . instance , activatedRoute } ) ;
@@ -232,43 +236,49 @@ export class IonRouterOutlet implements OnDestroy, OnInit {
232236 }
233237
234238 /**
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.
237241 */
238- private createActivatedRouteProxy ( activatedRoute : ActivatedRoute ) : ActivatedRoute {
242+ private createActivatedRouteProxy ( component$ : Observable < any > , activatedRoute : ActivatedRoute ) : ActivatedRoute {
239243 const proxy : any = new ActivatedRoute ( ) ;
244+
240245 proxy . _futureSnapshot = ( activatedRoute as any ) . _futureSnapshot ;
241246 proxy . _routerState = ( activatedRoute as any ) . _routerState ;
242247 proxy . snapshot = activatedRoute . snapshot ;
243248 proxy . outlet = activatedRoute . outlet ;
244249 proxy . component = activatedRoute . component ;
245250
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' ) ;
248259
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 ;
257261 }
258262
259263 /**
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
261265 */
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+ )
267277 ) ;
268278 }
269279
270280 /**
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
272282 */
273283 private updateActivatedRouteProxy ( component : any , activatedRoute : ActivatedRoute ) : void {
274284 const proxy = this . proxyMap . get ( component ) ;
0 commit comments