5

I've got a nav component which is a menu that handles a bit of route switching, the problem I have is that I can't seem to render the content of the routes because I don't have a router-outlet within the nav component template.

Instead I would like to render the content of the route in my main app component core, but how do I tell angular to use the router-outlet in my core component rather than in my nav component?

Since my [routerLink] is inside this template:

nav.component.html:

<nav class="nav-wrapper" [class.is-toggled]="isToggled" [class.is-hidden]="!isToggled">
  <ul class="nav-links">
    <li class="nav-link" *ngFor="#link of links">
      <a [routerLink]="link.href">
        <div class="label-wrapper">{{link.label}}</div>
        <div class="icon-wrapper"><i class="{{link.icon}}"></i></div>
      </a>
    </li>
  </ul>
</nav>

It doesn't want to render the route into the core component:

core.component.html:

<!-- The menu -->
<nav-list></nav-list> 

<!-- The router-outlet which should render the videos component -->
<router-outlet></router-outlet>

videos.component.html:

<h1>My videos</h1>

<!-- This should render the child views of the videos component -->
<router-outlet></router-outlet>

list.videos.component.html:

<h1>Videos list</h1>

So as you can see I want the bottom snippet to be rendered into the middle snippet which is then rendered at the top, inside the core component.

How can I do this?

The bottom line is that I DO NOT want to have a router-outlet in the nav component.

Chrillewoodz
  • 27,055
  • 21
  • 92
  • 175

3 Answers3

5

So I've a similar setup where I've a main layout component:

<shellheader (menuToggle)="onMenuToggle($event)"></shellheader>

<section id="main">
    <navigation [menuToggled]="menuToggled"></navigation>

    <section id="content">
        <div class="container">
            <div class="block-header">
                <h2>Header</h2>                    

                <router-outlet></router-outlet>

            </div>
        </div>
    </section>
</section>

<shellfooter></shellfooter>

Main layout component code:

@Component({
    templateUrl: "app/shell/main-layout.component.html",
    directives: [ROUTER_DIRECTIVES, NavigationComponent, HeaderComponent, FooterComponent]
})
@RouteConfig([
        { path: "/dashboard/...", name: "Dashboard", component: DashboardComponent, useAsDefault: true }
])
export class MainLayoutComponent {

    public menuToggled: boolean;

    public onMenuToggle(event:boolean) {
        this.menuToggled = event;
    }
}

And in my navigation component, I've got some router links (and no router outlet, only using routerlink directive, no child routes defined):

    <ul class="main-menu">
        <li *ngFor="#navItem of navItems">
            <a [routerLink]="navItem.route">
                <i *ngIf="navItem.icon" class="{{navItem.icon}}"></i>
                {{ navItem.text }}
            </a>
        </li>
    </ul>

Clicking those router links changes the route in the browser, and the outlet in the main component responds to those route changes.

You shouldn't need to have the router-outlet in your nav component. If the routes aren't rendering out to your main component, it's possible that you've not included the required directives in the main component e.g.:

import {RouteConfig, ROUTER_DIRECTIVES} from "angular2/router";

...

@Component({
    directives: [ROUTER_DIRECTIVES, ...]
})

Plunker: https://plnkr.co/edit/P6Bkwy?p=info

Further info: https://angular.io/docs/ts/latest/guide/router.html

MIP1983
  • 1,354
  • 1
  • 15
  • 25
  • Adding ROUTER_DIRECTIVES to the main app actually did the trick. Kinda frustrating that Angular doesn't tell you when you haven't injected something which you try to use in a template.. This was driving me insane so thanks A LOT! – Chrillewoodz Feb 05 '16 at 15:22
  • I'll throw you a bounty reward when I can :) – Chrillewoodz Feb 05 '16 at 15:23
  • I'm sure I made a similar mistake at one point, definitely a bit of a gotcha. I'm getting into the habit of there needing to be a directive injected if there's any kind of custom html tags e.g. on the page. – MIP1983 Feb 05 '16 at 15:26
0

It seams that you need Component router, consider this Code and Plunker:

@RouteConfig([
  { name: "Home", component: HomeCMP, path: "/home", useAsDefault: true},
  { name: "Videos", component: VideosCMP, path: "/videos/..."}
])

Than, in VideosCMP

@Component({
  selector: 'videos',
  template : `<router-outlet></router-outlet>`,
  directives: [RouterOutlet]
})
@RouteConfig([
  { name: "VideoList" component: VideListCMP, path: "/", useAsDefault: true}
])
export class VideosCMP {}

Full example: https://plnkr.co/edit/3dnBZEDhpGvVO5aQQswA?p=preview

Vlado Tesanovic
  • 6,369
  • 2
  • 20
  • 31
  • This still requires a router-outlet in the navigation component. There must be a way to avoid this. – Chrillewoodz Feb 05 '16 at 12:20
  • True, it requires. Why is that problem? – Vlado Tesanovic Feb 05 '16 at 12:35
  • Imagine if I have a narrow sidebar to the left that's about 50px wide and covers 100% of the height. Why would I want the content to go inside of that component? I will just mess up the layout, even if placed outside of the wrapper element. – Chrillewoodz Feb 05 '16 at 12:49
  • https://sketch.io/render/sketch56b4a61b03c33.png Is this what you want? If your main Cmp is: MainCmp in html of that Component, you can put and – Vlado Tesanovic Feb 05 '16 at 13:40
  • That's exactly what I've done, but it doesn't want to render into the core component anyway. – Chrillewoodz Feb 05 '16 at 14:34
0

<router-outlet> can be named and aux-routes add components to named `.

This Plunker from Brandon Roberts demonstrates it

in src/app.ts is an unamed <router-outlet> (main) for the normal route and several named <router-outlet name="chat"></router-outlet>.

In @RouteConfig the AuxRoutes are assigned to outlets by the path:.

AuxRoutes are still limited.
If this is not what you need @VladoTesanovic 's answer is probably the right way for you.

See Angular2 router in one component for information about the syntax in the new RC.3 router.

Community
  • 1
  • 1
Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
  • Doesn't make a whole lot of sense if I have to create every route as an Auxroute for the nav component to being able to find the router-outlet which it should render into. I don't think it will be able to find the router-outlet of the core component either. – Chrillewoodz Feb 05 '16 at 13:55
  • This is why I added "AuxRoutes are still limited" ;-). I just thought I might be helpful to point to them. It's the closes I know to what you asked for in Angula2 currently. – Günter Zöchbauer Feb 05 '16 at 13:58
  • Really strange way of doing it.. I'll try it out and see if I can get it to work at all. Thanks. – Chrillewoodz Feb 05 '16 at 14:00