Angular 2 router-outlet within component template

12,701

The way you call ContentComponent via <content> tag makes ContentComponent a child of your AppComponent and you can't place a router-outlet inside a child component's template. One way to achieve what you are after is to create a default route for the ContentComponent in the AppComponent:

@Routes([
    { path: '/', component: ContentComponent }
    { path: '/content', component: ContentComponent }
])

And AppComponent's template will be:

<header></header>     
<router-outlet></router-outlet>
<footer></footer>

Now you can define nested routes in your ContentComponent like this:

@Routes([
    { path: 'content1', component: Content1Component }
])
@Component({
    selector: 'content',
    template: `<router-outlet></router-outlet>`
})
export class ContentComponent { }

And if you have a menu in your header component and want to link to each nested content you can do this:

<a [routerLink]="['/content', 'content1']">Content1</a>

Which will load Content1Component into the ContentComponent's <router-outlet>

Share:
12,701
Colton Williams
Author by

Colton Williams

A demonstrated self-starter with experience working in leadership and as a team member with proven talent in front end web development and passion for problem solving.

Updated on June 29, 2022

Comments

  • Colton Williams
    Colton Williams almost 2 years

    I have been playing around with routes in Angular 2 but I have run into an issue that I cannot find an answer for. My routes are "working" but not the way I am hoping for. I am trying to use this like you would use ng-view from angular 1, my header and footer never change, and when my url changes new "stuff" is placed in my content.

    Here is what I have now which "works"

    import { Component } from '@angular/core';
    import { HeaderComponent } from './shared/header/header.component';
    import { ContentComponent } from './shared/content/content.component';
    import { FooterComponent } from './shared/footer/footer.component';
    import { TestComponent } from './components/test.component';
    import { Routes, ROUTER_DIRECTIVES, ROUTER_PROVIDERS } from '@angular/router';
    
    @Routes([
        {path: '/test', component: TestComponent }
    ])
    @Component({
        selector: 'app',
        template: `<header></header>
        <a [routerLink]="['/test']">Click for testComponent</a>
        <router-outlet></router-outlet>
        <footer></footer>`,
        directives: [HeaderComponent, ContentComponent, FooterComponent, ROUTER_DIRECTIVES]
    })
    export class AppComponent { }
    

    What I am trying to do is put the router outlet inside of my ContentComponentso that essentially the router just dumps the new stuff directly into the main area of my app. When I try to rewrite:
    <router-outlet></router-outlet>
    as
    <content><router-outlet></router-outlet></content>
    the routing stops working, no error message, just stops. I also do not see my testComponent in the DOM when I inspect it with the devtools. So I thought, well I will put the router-outlet inside the template of my ContentComponent like so:

    import { Component } from '@angular/core';
    
    @Component({
        selector: 'content',
        template: `<router-outlet></router-outlet>`
    })
    export class ContentComponent { }
    

    However when I do this I get the error message: Cannot find default outlet.

    I am missing something but the lack of documentation makes it very difficult to figure out, I would think there would be a way to define within @Routes where my outlet is but again, can't find any documentation that isn't for the deprecated-router. Hope someone can shed some light on this. Thanks in advance.

    Note: general code critiques would also be helpful, I am very new to Angular 2 and would love the advice.