@@ -54,11 +54,16 @@ export class Router {
5454 lastNavigationAttempt : string ;
5555
5656 private _currentInstruction : Instruction = null ;
57+
5758 private _currentNavigation : Promise < any > = _resolveToTrue ;
5859 private _outlet : RouterOutlet = null ;
59- private _auxOutlets : Map < string , RouterOutlet > = new Map ( ) ;
60+
61+ private _auxRouters : Map < string , Router > = new Map ( ) ;
62+ private _childRouter : Router ;
63+
6064 private _subject : EventEmitter = new EventEmitter ( ) ;
6165
66+
6267 constructor ( public registry : RouteRegistry , public _pipeline : Pipeline , public parent : Router ,
6368 public hostComponent : any ) { }
6469
@@ -67,26 +72,75 @@ export class Router {
6772 * Constructs a child router. You probably don't need to use this unless you're writing a reusable
6873 * component.
6974 */
70- childRouter ( hostComponent : any ) : Router { return new ChildRouter ( this , hostComponent ) ; }
75+ childRouter ( hostComponent : any ) : Router {
76+ return this . _childRouter = new ChildRouter ( this , hostComponent ) ;
77+ }
78+
7179
80+ /**
81+ * Constructs a child router. You probably don't need to use this unless you're writing a reusable
82+ * component.
83+ */
84+ auxRouter ( hostComponent : any ) : Router { return new ChildRouter ( this , hostComponent ) ; }
7285
7386 /**
74- * Register an object to notify of route changes. You probably don't need to use this unless
75- * you're writing a reusable component.
87+ * Register an outlet to notified of primary route changes.
88+ *
89+ * You probably don't need to use this unless you're writing a reusable component.
7690 */
77- registerOutlet ( outlet : RouterOutlet ) : Promise < boolean > {
91+ registerPrimaryOutlet ( outlet : RouterOutlet ) : Promise < boolean > {
7892 if ( isPresent ( outlet . name ) ) {
79- this . _auxOutlets . set ( outlet . name , outlet ) ;
80- } else {
81- this . _outlet = outlet ;
93+ throw new BaseException ( `registerAuxOutlet expects to be called with an unnamed outlet.` ) ;
8294 }
95+
96+ this . _outlet = outlet ;
8397 if ( isPresent ( this . _currentInstruction ) ) {
84- return outlet . commit ( this . _currentInstruction ) ;
98+ return this . commit ( this . _currentInstruction , false ) ;
99+ }
100+ return _resolveToTrue ;
101+ }
102+
103+ /**
104+ * Register an outlet to notified of auxiliary route changes.
105+ *
106+ * You probably don't need to use this unless you're writing a reusable component.
107+ */
108+ registerAuxOutlet ( outlet : RouterOutlet ) : Promise < boolean > {
109+ var outletName = outlet . name ;
110+ if ( isBlank ( outletName ) ) {
111+ throw new BaseException ( `registerAuxOutlet expects to be called with an outlet with a name.` ) ;
112+ }
113+
114+ // TODO...
115+ // what is the host of an aux route???
116+ var router = this . auxRouter ( this . hostComponent ) ;
117+
118+ this . _auxRouters . set ( outletName , router ) ;
119+ router . _outlet = outlet ;
120+
121+ var auxInstruction ;
122+ if ( isPresent ( this . _currentInstruction ) &&
123+ isPresent ( auxInstruction = this . _currentInstruction . auxInstruction [ outletName ] ) ) {
124+ return router . commit ( auxInstruction ) ;
85125 }
86126 return _resolveToTrue ;
87127 }
88128
89129
130+ /**
131+ * Given an instruction, returns `true` if the instruction is currently active,
132+ * otherwise `false`.
133+ */
134+ isRouteActive ( instruction : Instruction ) : boolean {
135+ var router = this ;
136+ while ( isPresent ( router . parent ) && isPresent ( instruction . child ) ) {
137+ router = router . parent ;
138+ instruction = instruction . child ;
139+ }
140+ return isPresent ( this . _currentInstruction ) &&
141+ this . _currentInstruction . component == instruction . component ;
142+ }
143+
90144 /**
91145 * Dynamically update the routing configuration and trigger a navigation.
92146 *
@@ -143,7 +197,7 @@ export class Router {
143197
144198 _navigate ( instruction : Instruction , _skipLocationChange : boolean ) : Promise < any > {
145199 return this . _settleInstruction ( instruction )
146- . then ( ( _ ) => this . _reuse ( instruction ) )
200+ . then ( ( _ ) => this . _canReuse ( instruction ) )
147201 . then ( ( _ ) => this . _canActivate ( instruction ) )
148202 . then ( ( result ) => {
149203 if ( ! result ) {
@@ -190,14 +244,17 @@ export class Router {
190244 } ) ;
191245 }
192246
193- _reuse ( instruction : Instruction ) : Promise < any > {
247+ /*
248+ * Recursively set reuse flags
249+ */
250+ _canReuse ( instruction : Instruction ) : Promise < any > {
194251 if ( isBlank ( this . _outlet ) ) {
195252 return _resolveToFalse ;
196253 }
197- return this . _outlet . canReuse ( instruction )
254+ return this . _outlet . canReuse ( instruction . component )
198255 . then ( ( result ) => {
199- if ( isPresent ( this . _outlet . childRouter ) && isPresent ( instruction . child ) ) {
200- return this . _outlet . childRouter . _reuse ( instruction . child ) ;
256+ if ( isPresent ( this . _childRouter ) && isPresent ( instruction . child ) ) {
257+ return this . _childRouter . _canReuse ( instruction . child ) ;
201258 }
202259 } ) ;
203260 }
@@ -211,19 +268,26 @@ export class Router {
211268 return _resolveToTrue ;
212269 }
213270 var next : Promise < boolean > ;
214- if ( isPresent ( instruction ) && instruction . component . reuse ) {
271+ var childInstruction : Instruction = null ;
272+ var reuse : boolean = false ;
273+ var componentInstruction : ComponentInstruction = null ;
274+ if ( isPresent ( instruction ) ) {
275+ childInstruction = instruction . child ;
276+ componentInstruction = instruction . component ;
277+ reuse = instruction . component . reuse ;
278+ }
279+ if ( reuse ) {
215280 next = _resolveToTrue ;
216281 } else {
217- next = this . _outlet . canDeactivate ( instruction ) ;
282+ next = this . _outlet . canDeactivate ( componentInstruction ) ;
218283 }
219284 // TODO: aux route lifecycle hooks
220285 return next . then ( ( result ) => {
221286 if ( result == false ) {
222287 return false ;
223288 }
224- if ( isPresent ( this . _outlet . childRouter ) ) {
225- return this . _outlet . childRouter . _canDeactivate ( isPresent ( instruction ) ? instruction . child :
226- null ) ;
289+ if ( isPresent ( this . _childRouter ) ) {
290+ return this . _childRouter . _canDeactivate ( childInstruction ) ;
227291 }
228292 return true ;
229293 } ) ;
@@ -234,13 +298,29 @@ export class Router {
234298 */
235299 commit ( instruction : Instruction , _skipLocationChange : boolean = false ) : Promise < any > {
236300 this . _currentInstruction = instruction ;
237- var next = _resolveToTrue ;
301+ var next : Promise < any > = _resolveToTrue ;
238302 if ( isPresent ( this . _outlet ) ) {
239- next = this . _outlet . commit ( instruction ) ;
303+ var componentInstruction = instruction . component ;
304+ if ( componentInstruction . reuse ) {
305+ next = this . _outlet . reuse ( componentInstruction ) ;
306+ } else {
307+ next =
308+ this . deactivate ( instruction ) . then ( ( _ ) => this . _outlet . activate ( componentInstruction ) ) ;
309+ }
310+ if ( isPresent ( instruction . child ) ) {
311+ next = next . then ( ( _ ) => {
312+ if ( isPresent ( this . _childRouter ) ) {
313+ return this . _childRouter . commit ( instruction . child ) ;
314+ }
315+ } ) ;
316+ }
240317 }
318+
241319 var promises = [ ] ;
242- MapWrapper . forEach ( this . _auxOutlets ,
243- ( outlet , _ ) => { promises . push ( outlet . commit ( instruction ) ) ; } ) ;
320+ MapWrapper . forEach ( this . _auxRouters , ( router , name ) => {
321+ promises . push ( router . commit ( instruction . auxInstruction [ name ] ) ) ;
322+ } ) ;
323+
244324 return next . then ( ( _ ) => PromiseWrapper . all ( promises ) ) ;
245325 }
246326
@@ -262,10 +342,23 @@ export class Router {
262342 * Removes the contents of this router's outlet and all descendant outlets
263343 */
264344 deactivate ( instruction : Instruction ) : Promise < any > {
345+ var childInstruction : Instruction = null ;
346+ var componentInstruction : ComponentInstruction = null ;
347+ if ( isPresent ( instruction ) ) {
348+ childInstruction = instruction . child ;
349+ componentInstruction = instruction . component ;
350+ }
351+ var next : Promise < any > = _resolveToTrue ;
352+ if ( isPresent ( this . _childRouter ) ) {
353+ next = this . _childRouter . deactivate ( childInstruction ) ;
354+ }
265355 if ( isPresent ( this . _outlet ) ) {
266- return this . _outlet . deactivate ( instruction ) ;
356+ next = next . then ( ( _ ) => this . _outlet . deactivate ( componentInstruction ) ) ;
267357 }
268- return _resolveToTrue ;
358+
359+ // TODO: handle aux routes
360+
361+ return next ;
269362 }
270363
271364
0 commit comments