Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Populating a child router-outlet Angular2

Since I heard Angular's Router supports nested <router-outlet> tags, I'm trying to use two of them. I"m using the latest Angular-CLI, converting from ui-router to Angular's Router. I can't get the second router-outlet to populate content.

(The parent routing is working fine) app-routing.module.ts

...
const routes: Routes = [
    { path: '', pathMatch: 'full', component: LoginComponent },
    { path: 'login', pathMatch: 'full', component: LoginComponent },
    { path: 'dashboard',
        pathMatch: 'full',
        component: DashboardComponent // this holds the second router-outlet
    },
    { path: '**', component: LoginComponent }
];

@NgModule({
    imports: [
        RouterModule.forRoot(routes)
    ],
    exports: [ RouterModule ]
})
export class AppRoutingModule { }

app.component.ts -- this just holds the router-outlet, and works fine at the top level...

<router-outlet></router-outlet>

The dashboard holds universal headers, footers, sidebars, etc. So that's why I want it in the top-level router-outlet. The sub-router-outlet will populate child views, but doesn't populate.

Attempt 1 dashboard-routing.module.ts

export const dashboardRoutes: Routes = [
    { path: '', pathMatch: 'full', redirectTo: 'home' },
    { path: 'home', pathMatch: 'full', component: HomeComponent },
    { path: 'about', pathMatch: 'full', component: AboutComponent }
]
@NgModule({
    imports: [
        RouterModule.forChild(dashboardRoutes)
    ],
    exports: [ RouterModule ]
})
export class DashboardRoutingModule { }

Attempt 2 dashboard-routing.module.ts as per Angular2 : Multiple Router-Outlets & Router-Outlets Inside Child Route

export const dashboardRoutes: Routes = [
    {
        path: 'dashboard',
        children:[
            { path: '', component: DashboardComponent},
            { path: 'home', component: HomeComponent},
            { path: 'about', component: AboutComponent}
        ]
    }
 ]
@NgModule({
    imports: [
        RouterModule.forChild(dashboardRoutes)
    ],
    exports: [ RouterModule ]
})
export class DashboardRoutingModule { }

Inside the Dashboard template, this nested router-outlet does not populate. Instead, the top-level router-outlet in the app.component.html is populated instead :(

dashboard.component.html

<header>...</header>
<aside class="sidenav">...<aside>

<!-- why can't I populate you? -->
<router-outlet></router-outlet>

************** Answer, a great thank you to PierreDuc! **************

app-routing.module.ts

// seems counter-intuitive that the dashboard component isn't actually in here..., but it works!
const routes: Routes = [
    { path: '', pathMatch: 'full', component: LoginComponent },
    { path: 'login', pathMatch: 'full', component: LoginComponent },
    { path: '**', component: LoginComponent }
];
@NgModule({
    imports: [
        RouterModule.forRoot(routes),
        DashboardRoutingModule // this is the magic. I'm assuming to put it second is better (though putting it first didn't seem to have any immediate negative effect)
    ],
    exports: [ RouterModule ]
})
export class AppRoutingModule { }

dashboard-routing.module.ts

export const dashboardRoutes: Routes = [
    {
        path: 'dashboard',
        component: DashboardComponent,
        children:[
            { path: '', component: HomeComponent },
            { path: 'home', pathMatch: 'full', component: HomeComponent },
            { path: 'about', pathMatch: 'full', component: AboutComponent }
        ]
    }
]
@NgModule({
    imports: [
        RouterModule.forChild(dashboardRoutes)
    ],
    exports: [ RouterModule ]
})
export class DashboardRoutingModule { }

Here's how to navigate from the root:

login.component.ts

... passed validation ...
this._router.navigate(['/dashboard']);
this._router.navigate(['/dashboard/home']);

or routing via routerLink via a sidebar in the Dashboard dashboard.component.html

[routerLink]="['../login']" <!-- back to login, though the '../' seems less than ideal

or in the dashboard view via routerLink to child router-outlets: dashboard.component.html:

[routerLink]="['../about']"
like image 480
curtybear Avatar asked Mar 05 '17 18:03

curtybear


People also ask

Can we have multiple router outlet?

You can have multiple router-outlet in same template by configuring your router and providing name to your router-outlet, you can achieve this as follows.

Can we pass data in router outlet in Angular?

There are various ways by which we can pass data from one component to another. Angular 7.2. 0 introduced a new way to pass data using State Object while navigating between routed components.


1 Answers

Child router-outlets are populated with the children array inside the router configuration. But there's duplication going on. You should remove the dashboard entry inside your AppRoutingModule, and go for attempt 2:

app-routes

const routes: Routes = [
    { path: '', pathMatch: 'full', component: LoginComponent },
    { path: 'login', pathMatch: 'full', component: LoginComponent },
    { path: '**', component: LoginComponent }
];

And keep your DashboardRoutingModule as is it is in attempt 2 (with the children array), and import this module either inside the AppRoutingModule, or in the AppModule.

like image 176
Poul Kruijt Avatar answered Nov 16 '22 00:11

Poul Kruijt