Reputation: 1712
I would like to have a routing module in my main app plus routing in a separate module, like:
app
- modules
-my-module
my-routing.module.ts
app-routing.module.ts
The main routing module has:
const routes: Routes = [
{ path: '', pathMatch: 'full', redirectTo: 'view-container' },
{ path: 'view-container', component: ViewContainerComponent },
{ path: '**', component: ViewContainerComponent }
];
@NgModule({
imports: [RouterModule.forRoot(routes, { enableTracing: true })],
exports: [RouterModule]
})
export class AppRoutingModule { }
The sub module's routing is:
const routes: Routes = [
{ path: 'view-detail', component: CompADetailComponent }
];
@NgModule({
imports: [
CommonModule,
RouterModule.forChild(routes)
],
declarations: []
})
export class MyRoutingModule { }
My ViewContainer component has a routerLink to "view-detail".
<a [routerLink]="['/view-detail']">
View Details
</a>
However, when I click on the "View Details" link, only the URL changes, the CompADetailComponent is not loaded.
I do note that if I move the "view-detail" path to the main app routing module it works fine. In the tracing, the difference I see is:
When it works:
Router Event: NavigationStart
platform-browser.js:367 NavigationStart(id: 2, url: '/view-detail')
platform-browser.js:367 NavigationStart {id: 2, url: "/view-detail"}
platform-browser.js:380 Router Event: RoutesRecognized
platform-browser.js:367 RoutesRecognized(id: 2, url: '/view-detail', urlAfterRedirects: '/view-detail', state: Route(url:'', path:'') { Route(url:'view-detail', path:'view-detail') } )
platform-browser.js:367 RoutesRecognized {id: 2, url: "/view-detail", urlAfterRedirects: "/view-detail", state: RouterStateSnapshot}
platform-browser.js:380 Router Event: GuardsCheckStart
platform-browser.js:367 GuardsCheckStart(id: 2, url: '/view-detail', urlAfterRedirects: '/view-detail', state: Route(url:'', path:'') { Route(url:'view-detail', path:'view-detail') } )
platform-browser.js:367 GuardsCheckStart {id: 2, url: "/view-detail", urlAfterRedirects: UrlTree, state: RouterStateSnapshot}
platform-browser.js:380 Router Event: ChildActivationStart
platform-browser.js:367 ChildActivationStart(path: '')
platform-browser.js:367 ChildActivationStart {snapshot: ActivatedRouteSnapshot}
platform-browser.js:380 Router Event: ActivationStart
platform-browser.js:367 ActivationStart(path: 'view-detail')
platform-browser.js:367 ActivationStart {snapshot: ActivatedRouteSnapshot}
platform-browser.js:380 Router Event: GuardsCheckEnd
platform-browser.js:367 GuardsCheckEnd(id: 2, url: '/view-detail', urlAfterRedirects: '/view-detail', state: Route(url:'', path:'') { Route(url:'view-detail', path:'view-detail') } , shouldActivate: true)
platform-browser.js:367 GuardsCheckEnd {id: 2, url: "/view-detail", urlAfterRedirects: UrlTree, state: RouterStateSnapshot, shouldActivate: true}
platform-browser.js:380 Router Event: ResolveStart
platform-browser.js:367 ResolveStart(id: 2, url: '/view-detail', urlAfterRedirects: '/view-detail', state: Route(url:'', path:'') { Route(url:'view-detail', path:'view-detail') } )
platform-browser.js:367 ResolveStart {id: 2, url: "/view-detail", urlAfterRedirects: UrlTree, state: RouterStateSnapshot}
platform-browser.js:380 Router Event: ResolveEnd
platform-browser.js:367 ResolveEnd(id: 2, url: '/view-detail', urlAfterRedirects: '/view-detail', state: Route(url:'', path:'') { Route(url:'view-detail', path:'view-detail') } )
platform-browser.js:367 ResolveEnd {id: 2, url: "/view-detail", urlAfterRedirects: UrlTree, state: RouterStateSnapshot}
platform-browser.js:380 Router Event: ActivationEnd
platform-browser.js:367 ActivationEnd(path: 'view-detail')
platform-browser.js:367 ActivationEnd {snapshot: ActivatedRouteSnapshot}
platform-browser.js:380 Router Event: ChildActivationEnd
platform-browser.js:367 ChildActivationEnd(path: '')
platform-browser.js:367 ChildActivationEnd {snapshot: ActivatedRouteSnapshot}
platform-browser.js:380 Router Event: NavigationEnd
platform-browser.js:367 NavigationEnd(id: 2, url: '/view-detail', urlAfterRedirects: '/view-detail')
platform-browser.js:367 NavigationEnd {id: 2, url: "/view-detail", urlAfterRedirects: "/view-detail"}
When it doesn't work:
Router Event: NavigationStart
platform-browser.js:367 NavigationStart(id: 2, url: '/view-detail')
platform-browser.js:367 NavigationStart {id: 2, url: "/view-detail"}
platform-browser.js:380 Router Event: RoutesRecognized
platform-browser.js:367 RoutesRecognized(id: 2, url: '/view-detail', urlAfterRedirects: '/view-detail', state: Route(url:'', path:'') { Route(url:'view-detail', path:'**') } )
platform-browser.js:367 RoutesRecognized {id: 2, url: "/view-detail", urlAfterRedirects: "/view-detail", state: RouterStateSnapshot}
platform-browser.js:380 Router Event: GuardsCheckStart
platform-browser.js:367 GuardsCheckStart(id: 2, url: '/view-detail', urlAfterRedirects: '/view-detail', state: Route(url:'', path:'') { Route(url:'view-detail', path:'**') } )
platform-browser.js:367 GuardsCheckStart {id: 2, url: "/view-detail", urlAfterRedirects: UrlTree, state: RouterStateSnapshot}
platform-browser.js:380 Router Event: ChildActivationStart
platform-browser.js:367 ChildActivationStart(path: '')
platform-browser.js:367 ChildActivationStart {snapshot: ActivatedRouteSnapshot}
platform-browser.js:380 Router Event: ActivationStart
platform-browser.js:367 ActivationStart(path: '**')
platform-browser.js:367 ActivationStart {snapshot: ActivatedRouteSnapshot}
platform-browser.js:380 Router Event: GuardsCheckEnd
platform-browser.js:367 GuardsCheckEnd(id: 2, url: '/view-detail', urlAfterRedirects: '/view-detail', state: Route(url:'', path:'') { Route(url:'view-detail', path:'**') } , shouldActivate: true)
platform-browser.js:367 GuardsCheckEnd {id: 2, url: "/view-detail", urlAfterRedirects: UrlTree, state: RouterStateSnapshot, shouldActivate: true}
platform-browser.js:380 Router Event: ResolveStart
platform-browser.js:367 ResolveStart(id: 2, url: '/view-detail', urlAfterRedirects: '/view-detail', state: Route(url:'', path:'') { Route(url:'view-detail', path:'**') } )
platform-browser.js:367 ResolveStart {id: 2, url: "/view-detail", urlAfterRedirects: UrlTree, state: RouterStateSnapshot}
platform-browser.js:380 Router Event: ResolveEnd
platform-browser.js:367 ResolveEnd(id: 2, url: '/view-detail', urlAfterRedirects: '/view-detail', state: Route(url:'', path:'') { Route(url:'view-detail', path:'**') } )
platform-browser.js:367 ResolveEnd {id: 2, url: "/view-detail", urlAfterRedirects: UrlTree, state: RouterStateSnapshot}
platform-browser.js:380 Router Event: ActivationEnd
platform-browser.js:367 ActivationEnd(path: '**')
platform-browser.js:367 ActivationEnd {snapshot: ActivatedRouteSnapshot}
platform-browser.js:380 Router Event: ChildActivationEnd
platform-browser.js:367 ChildActivationEnd(path: '')
platform-browser.js:367 ChildActivationEnd {snapshot: ActivatedRouteSnapshot}
platform-browser.js:380 Router Event: NavigationEnd
platform-browser.js:367 NavigationEnd(id: 2, url: '/view-detail', urlAfterRedirects: '/view-detail')
platform-browser.js:367 NavigationEnd {id: 2, url: "/view-detail", urlAfterRedirects: "/view-detail"}
So it seems to be picking up the "**" path instead of the "view-detail" path. Any clue what I'm doing wrong?
* EDIT * App module added:
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { AppRoutingModule } from './app-routing.module';
import { CompAModule } from './modules/comp-a/comp-a.module';
import { ViewContainerComponent } from './view-container/view-container.component';
import { CompADetailComponent } from './modules/comp-a-detail/comp-a-detail.component';
import { MyRoutingModule } from './modules/my-module/my-routing.module';
@NgModule({
declarations: [
AppComponent,
ViewContainerComponent,
CompADetailComponent
],
imports: [
BrowserModule,
AppRoutingModule,
MyRoutingModule,
CompAModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Upvotes: 2
Views: 2345
Reputation: 60626
The imports array here:
imports: [
BrowserModule,
AppRoutingModule,
MyRoutingModule,
CompAModule
],
Defines the ordering of your routes. So as you have it here, Angular will merge your routes together in the following order.
{ path: '', pathMatch: 'full', redirectTo: 'view-container' },
{ path: 'view-container', component: ViewContainerComponent },
{ path: '**', component: ViewContainerComponent }
{ path: 'view-detail', component: CompADetailComponent }
Since Angular processes routes "first match wins" ... it will always find your '**' route before your 'view-detail' route.
You just need to swap the order in the imports array:
imports: [
BrowserModule,
MyRoutingModule,
CompAModule,
AppRoutingModule
],
I have a blog post that walks through the details (and exceptions) to the route ordering rules here: https://blogs.msmvps.com/deborahk/angular-route-ordering/
Upvotes: 8